From e0b0a66be19d01448ba562c00cb3ba5f8ab55afb Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 23 Dec 2015 16:29:03 +0100 Subject: [PATCH 1/4] Make FormatOptions.of(format) return CsvOptions if format is CSV --- .../main/java/com/google/gcloud/bigquery/FormatOptions.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FormatOptions.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FormatOptions.java index e1f9d5aeb545..ebf9f651a8d2 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FormatOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FormatOptions.java @@ -85,6 +85,9 @@ public static FormatOptions datastoreBackup() { * Default options for the provided format. */ public static FormatOptions of(String format) { + if (format.equals(CSV)) { + return csv(); + } return new FormatOptions(format); } } From 30fa22ac9bd83d386223e16c37b1d974dfe7348d Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 23 Dec 2015 16:30:06 +0100 Subject: [PATCH 2/4] Minor style fixes to DatastoreExample and StorageExample --- .../gcloud/examples/DatastoreExample.java | 9 ++++--- .../gcloud/examples/StorageExample.java | 26 +++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java index 93bb1b5b93b4..0951e3e93978 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DatastoreExample.java @@ -37,10 +37,10 @@ /** * An example of using the Google Cloud Datastore. - *

- * This example adds, display or clear comments for a given user. - *

- * Steps needed for running the example:

    + * + *

    This example adds, display or clear comments for a given user. + * + *

    Steps needed for running the example:

      *
    1. login using gcloud SDK - {@code gcloud auth login}.
    2. *
    3. compile using maven - {@code mvn compile}
    4. *
    5. run using maven - {@code mvn exec:java @@ -58,6 +58,7 @@ public class DatastoreExample { private interface DatastoreAction { void run(Transaction tx, Key userKey, String... args); + String getRequiredParams(); } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java index abd912aacd23..e042e8eb54bc 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java @@ -59,27 +59,27 @@ /** * An example of using the Google Cloud Storage. - *

      - * This example demonstrates a simple/typical storage usage. - *

      - * Steps needed for running the example: + * + *

      This example demonstrates a simple/typical storage usage. + * + *

      Steps needed for running the example: *

        *
      1. login using gcloud SDK - {@code gcloud auth login}.
      2. *
      3. compile using maven - {@code mvn compile}
      4. *
      5. run using maven - * {@code mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.StorageExample" - * -Dexec.args="[] list []| info [ []]| - * download [local_file]| upload []| - * delete +| cp | - * compose + | update_metadata [key=value]*| + * -Dexec.args="[] list [] | info [ []] | + * download [local_file] | upload [] | + * delete + | cp | + * compose + | update_metadata [key=value]* | * sign_url "} *
      6. *
      * - * The first parameter is an optional project_id (logged-in project will be used if not supplied). - * Second parameter is a Storage operation (list, delete, compose,...) to demonstrate the its - * usage. Any other arguments are specific to the operation. - * See each action's run method for the specific Storage interaction. + *

      The first parameter is an optional {@code project_id} (logged-in project will be used if not + * supplied). Second parameter is a Storage operation (list, delete, compose,...) and can be used to + * demonstrate its usage. Any other arguments are specific to the operation. See each action's run + * method for the specific Storage interaction. */ public class StorageExample { @@ -523,7 +523,7 @@ public String params() { ACTIONS.put("sign_url", new SignUrlAction()); } - public static void printUsage() { + private static void printUsage() { StringBuilder actionAndParams = new StringBuilder(); for (Map.Entry entry : ACTIONS.entrySet()) { actionAndParams.append("\n\t").append(entry.getKey()); From 48acfefd10a7af67fd46ea77438dc0cfd7b7c486 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 23 Dec 2015 16:40:17 +0100 Subject: [PATCH 3/4] Add bigquery module to gcloud-java pom --- gcloud-java/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 655ef8f70e62..74904ae040a6 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -14,6 +14,11 @@ 0.1.1-SNAPSHOT + + ${project.groupId} + gcloud-java-bigquery + ${project.version} + ${project.groupId} gcloud-java-core From d5e4dba23a3b34858100ae2c04f6dd413030f4f0 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 23 Dec 2015 16:41:33 +0100 Subject: [PATCH 4/4] Add BigQuery example --- README.md | 4 + gcloud-java-examples/README.md | 10 + .../gcloud/examples/BigQueryExample.java | 686 ++++++++++++++++++ 3 files changed, 700 insertions(+) create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java diff --git a/README.md b/README.md index 7a2e3afc8a47..e67b58cb8d67 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,10 @@ Example Applications - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/DatastoreExample.html). - [`StorageExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/StorageExample.java) - A simple command line interface providing some of Cloud Storage's functionality - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/StorageExample.html). +- [`ResourceManagerExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality + - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/ResourceManagerExample.html). +- [`BigQueryExample`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality + - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/BigQueryExample.html). Specifying a Project ID ----------------------- diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 7dfcd13db755..404310c646f8 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -67,6 +67,16 @@ To run examples from your command line: $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.ResourceManagerExample" -Dexec.args="get my-project-id" ``` + Here's an example run of `BigQueryExample`. + + Before running the example, go to the [Google Developers Console][developers-console] to ensure that Google Cloud BigQuery API is enabled. + ``` + $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="create dataset new_dataset_id" + $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="create table new_dataset_id new_table_id field_name:string" + $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="list tables new_dataset_id" + $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" -Dexec.args="query 'select * from new_dataset_id.new_table_id'" + ``` + Troubleshooting --------------- diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java new file mode 100644 index 000000000000..eb46bc69adf4 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/BigQueryExample.java @@ -0,0 +1,686 @@ +/* + * 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 com.google.gcloud.examples; + +import com.google.common.collect.ImmutableMap; +import com.google.gcloud.bigquery.BaseTableInfo; +import com.google.gcloud.bigquery.BigQuery; +import com.google.gcloud.bigquery.BigQueryError; +import com.google.gcloud.bigquery.BigQueryOptions; +import com.google.gcloud.bigquery.CopyJobInfo; +import com.google.gcloud.bigquery.DatasetId; +import com.google.gcloud.bigquery.DatasetInfo; +import com.google.gcloud.bigquery.ExternalDataConfiguration; +import com.google.gcloud.bigquery.ExternalTableInfo; +import com.google.gcloud.bigquery.ExtractJobInfo; +import com.google.gcloud.bigquery.Field; +import com.google.gcloud.bigquery.FieldValue; +import com.google.gcloud.bigquery.FormatOptions; +import com.google.gcloud.bigquery.JobId; +import com.google.gcloud.bigquery.JobInfo; +import com.google.gcloud.bigquery.JobStatus; +import com.google.gcloud.bigquery.LoadJobInfo; +import com.google.gcloud.bigquery.QueryRequest; +import com.google.gcloud.bigquery.QueryResponse; +import com.google.gcloud.bigquery.Schema; +import com.google.gcloud.bigquery.TableId; +import com.google.gcloud.bigquery.TableInfo; +import com.google.gcloud.bigquery.ViewInfo; +import com.google.gcloud.spi.BigQueryRpc.Tuple; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * An example of using the Google BigQuery. + * + *

      This example demonstrates a simple/typical BigQuery usage. + * + *

      Steps needed for running the example: + *

        + *
      1. login using gcloud SDK - {@code gcloud auth login}.
      2. + *
      3. compile using maven - {@code mvn compile}
      4. + *
      5. run using maven - + * {@code mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.BigQueryExample" + * -Dexec.args="[] list datasets | list tables | list jobs | + * list data | info dataset | info table
        | + * info job | create dataset | + * create table
        (:)+ | + * create view
        | + * create external-table
        (:)+ | + * delete dataset | delete table
        | cancel | + * copy | + * load
        + | + * extract
        + | query "} + * + * + * + *

        The first parameter is an optional {@code project_id} (logged-in project will be used if not + * supplied). Second parameter is a BigQuery operation and can be used to demonstrate its usage. For + * operations that apply to more than one entity (`list`, `create`, `info` and `delete`) the third + * parameter specifies the entity. {@code } indicates that only primitive types are + * supported by the {@code create table} and {@code create external-table} operations + * ({@code string}, {@code float}, {@code integer}, {@code timestamp}, {@code boolean}). + * {@code }, {@code } and {@code } parameters are URIs to + * Google Cloud Storage blobs, in the form {@code gs://bucket/path}. See each action's run method + * for the specific BigQuery interaction. + */ +public class BigQueryExample { + + private static final Map CREATE_ACTIONS = new HashMap<>(); + private static final Map INFO_ACTIONS = new HashMap<>(); + private static final Map LIST_ACTIONS = new HashMap<>(); + private static final Map DELETE_ACTIONS = new HashMap<>(); + private static final Map ACTIONS = new HashMap<>(); + + private abstract static class BigQueryAction { + + abstract void run(BigQuery bigquery, T request) throws Exception; + + abstract T parse(String... args) throws Exception; + + protected String params() { + return ""; + } + } + + private static class ParentAction extends BigQueryAction> { + + private final Map subActions; + + public ParentAction(Map subActions) { + this.subActions = ImmutableMap.copyOf(subActions); + } + + @Override + @SuppressWarnings("unchecked") + void run(BigQuery bigquery, Tuple subaction) throws Exception { + subaction.x().run(bigquery, subaction.y()); + } + + @Override + Tuple parse(String... args) throws Exception { + if (args.length >= 1) { + BigQueryAction action = subActions.get(args[0]); + if (action != null) { + Object actionArguments = action.parse(Arrays.copyOfRange(args, 1, args.length)); + return Tuple.of(action, actionArguments); + } + } + throw new IllegalArgumentException(); + } + + @Override + public String params() { + StringBuilder builder = new StringBuilder(); + for (Map.Entry entry : subActions.entrySet()) { + builder.append("\n").append(entry.getKey()); + String param = entry.getValue().params(); + if (param != null && !param.isEmpty()) { + builder.append(' ').append(param); + } + } + return builder.toString(); + } + } + + private abstract static class VoidAction extends BigQueryAction { + @Override + Void parse(String... args) throws Exception { + if (args.length == 0) { + return null; + } + throw new IllegalArgumentException(); + } + } + + /** + * This class demonstrates how to list BigQuery Datasets. + * + * @see Datasets: list + * + */ + private static class ListDatasetsAction extends VoidAction { + @Override + public void run(BigQuery bigquery, Void arg) { + Iterator datasetInfoIterator = bigquery.listDatasets().iterateAll(); + while (datasetInfoIterator.hasNext()) { + System.out.println(datasetInfoIterator.next()); + } + } + } + + private abstract static class DatasetAction extends BigQueryAction { + @Override + DatasetId parse(String... args) throws Exception { + if (args.length == 1) { + return DatasetId.of(args[0]); + } + throw new IllegalArgumentException(); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to list BigQuery Tables in a Dataset. + * + * @see Tables: list + */ + private static class ListTablesAction extends DatasetAction { + @Override + public void run(BigQuery bigquery, DatasetId datasetId) { + Iterator tableInfoIterator = bigquery.listTables(datasetId).iterateAll(); + while (tableInfoIterator.hasNext()) { + System.out.println(tableInfoIterator.next()); + } + } + } + + /** + * This class demonstrates how to retrieve information on a BigQuery Dataset. + * + * @see Datasets: get + * + */ + private static class DatasetInfoAction extends DatasetAction { + @Override + public void run(BigQuery bigquery, DatasetId datasetId) { + System.out.println("Dataset info: " + bigquery.getDataset(datasetId)); + } + } + + /** + * This class demonstrates how to create a BigQuery Dataset. + * + * @see Datasets: + * insert + */ + private static class CreateDatasetAction extends DatasetAction { + @Override + public void run(BigQuery bigquery, DatasetId datasetId) { + bigquery.create(DatasetInfo.builder(datasetId).build()); + System.out.println("Created dataset " + datasetId); + } + } + + /** + * This class demonstrates how to delete a BigQuery Dataset. + * + * @see Datasets: + * delete + */ + private static class DeleteDatasetAction extends DatasetAction { + @Override + public void run(BigQuery bigquery, DatasetId datasetId) { + bigquery.delete(datasetId); + System.out.println("Dataset " + datasetId + " was deleted"); + } + } + + private abstract static class TableAction extends BigQueryAction { + @Override + TableId parse(String... args) throws Exception { + if (args.length == 2) { + return TableId.of(args[0], args[1]); + } + throw new IllegalArgumentException(); + } + + @Override + public String params() { + return "

        "; + } + } + + /** + * This class demonstrates how to retrieve information on a BigQuery Table. + * + * @see Tables: get + */ + private static class TableInfoAction extends TableAction { + @Override + public void run(BigQuery bigquery, TableId tableId) { + System.out.println("Table info: " + bigquery.getTable(tableId)); + } + } + + /** + * This class demonstrates how to delete a BigQuery Table. + * + * @see Tables: delete + * + */ + private static class DeleteTableAction extends TableAction { + @Override + public void run(BigQuery bigquery, TableId tableId) { + bigquery.delete(tableId); + System.out.println("Table " + tableId + " was deleted"); + } + } + + /** + * This class demonstrates how to list the rows in a BigQuery Table. + * + * @see Tabledata: + * list + */ + private static class ListTableDataAction extends TableAction { + @Override + public void run(BigQuery bigquery, TableId tableId) { + Iterator> iterator = bigquery.listTableData(tableId).iterateAll(); + while (iterator.hasNext()) { + System.out.println(iterator.next()); + } + } + } + + private abstract static class JobAction extends BigQueryAction { + @Override + JobId parse(String... args) throws Exception { + if (args.length == 1) { + return JobId.of(args[0]); + } + throw new IllegalArgumentException(); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to list BigQuery Jobs. + * + * @see Jobs: list + */ + private static class ListJobsAction extends VoidAction { + @Override + public void run(BigQuery bigquery, Void arg) { + Iterator datasetInfoIterator = bigquery.listJobs().iterateAll(); + while (datasetInfoIterator.hasNext()) { + System.out.println(datasetInfoIterator.next()); + } + } + } + + /** + * This class demonstrates how to retrieve information on a BigQuery Job. + * + * @see Jobs: get + */ + private static class JobInfoAction extends JobAction { + @Override + public void run(BigQuery bigquery, JobId jobId) { + System.out.println("Job info: " + bigquery.getJob(jobId)); + } + } + + /** + * This class demonstrates how to cancel a BigQuery Job. + * + * @see Jobs: cancel + */ + private static class CancelJobAction extends JobAction { + @Override + public void run(BigQuery bigquery, JobId jobId) { + bigquery.cancel(jobId); + System.out.println("Requested cancel for job " + jobId); + } + } + + private abstract static class CreateTableAction extends BigQueryAction { + @Override + void run(BigQuery bigquery, BaseTableInfo table) throws Exception { + BaseTableInfo createTable = bigquery.create(table); + System.out.println("Created table " + createTable.tableId()); + System.out.println(createTable.toString()); + } + + static Schema parseSchema(String[] args, int start, int end) { + Schema.Builder builder = Schema.builder(); + for (int i = start; i < end; i++) { + String[] fieldsArray = args[i].split(":"); + if (fieldsArray.length != 2) { + throw new IllegalArgumentException(); + } + String fieldName = fieldsArray[0]; + String typeString = fieldsArray[1]; + Field.Type fieldType; + switch (typeString) { + case "string": + fieldType = Field.Type.string(); + break; + case "integer": + fieldType = Field.Type.integer(); + break; + case "timestamp": + fieldType = Field.Type.timestamp(); + break; + case "float": + fieldType = Field.Type.floatingPoint(); + break; + case "boolean": + fieldType = Field.Type.bool(); + break; + default: + throw new IllegalArgumentException(); + } + builder.addField(Field.of(fieldName, fieldType)); + } + return builder.build(); + } + } + + /** + * This class demonstrates how to create a simple BigQuery Table (i.e. a table of type + * {@link BaseTableInfo.Type#TABLE}). + * + * @see Tables: insert + * + */ + private static class CreateSimpleTableAction extends CreateTableAction { + @Override + BaseTableInfo parse(String... args) throws Exception { + if (args.length >= 3) { + String dataset = args[0]; + String table = args[1]; + TableId tableId = TableId.of(dataset, table); + return TableInfo.of(tableId, parseSchema(args, 2, args.length)); + } + throw new IllegalArgumentException(); + } + + @Override + protected String params() { + return "
        (:)+"; + } + } + + /** + * This class demonstrates how to create a BigQuery External Table (i.e. a table of type + * {@link BaseTableInfo.Type#EXTERNAL}). + * + * @see Tables: insert + * + */ + private static class CreateExternalTableAction extends CreateTableAction { + @Override + BaseTableInfo parse(String... args) throws Exception { + if (args.length >= 5) { + String dataset = args[0]; + String table = args[1]; + TableId tableId = TableId.of(dataset, table); + ExternalDataConfiguration configuration = + ExternalDataConfiguration.of(args[args.length - 1], + parseSchema(args, 3, args.length - 1), FormatOptions.of(args[2])); + return ExternalTableInfo.of(tableId, configuration); + } + throw new IllegalArgumentException(); + } + + @Override + protected String params() { + return "
        (:)+ "; + } + } + + /** + * This class demonstrates how to create a BigQuery View Table (i.e. a table of type + * {@link BaseTableInfo.Type#VIEW}). + * + * @see Tables: insert + * + */ + private static class CreateViewAction extends CreateTableAction { + @Override + BaseTableInfo parse(String... args) throws Exception { + if (args.length == 3) { + String dataset = args[0]; + String table = args[1]; + String query = args[2]; + TableId tableId = TableId.of(dataset, table); + return ViewInfo.of(tableId, query); + } + throw new IllegalArgumentException(); + } + + @Override + protected String params() { + return "
        "; + } + } + + private abstract static class JobRunAction extends BigQueryAction { + @Override + void run(BigQuery bigquery, JobInfo job) throws Exception { + System.out.println("Creating job"); + JobInfo startedJob = bigquery.create(job); + while (startedJob.status().state() != JobStatus.State.DONE) { + System.out.println("Waiting for job " + startedJob.jobId().job() + " to complete"); + Thread.sleep(1000L); + startedJob = bigquery.getJob(startedJob.jobId()); + } + if (startedJob.status().error() == null) { + System.out.println("Job " + startedJob.jobId().job() + " suceeded"); + } else { + System.out.println("Job " + startedJob.jobId().job() + " failed"); + System.out.println("Error: " + startedJob.status().error()); + } + } + } + + /** + * This class demonstrates how to create a BigQuery Load Job and wait for it to complete. + * + * @see Jobs: insert + */ + private static class LoadAction extends JobRunAction { + @Override + LoadJobInfo parse(String... args) throws Exception { + if (args.length >= 4) { + String dataset = args[0]; + String table = args[1]; + String format = args[2]; + TableId tableId = TableId.of(dataset, table); + return LoadJobInfo.builder(tableId, Arrays.asList(args).subList(3, args.length)) + .formatOptions(FormatOptions.of(format)) + .build(); + } + throw new IllegalArgumentException(); + } + + @Override + protected String params() { + return "
        +"; + } + } + + /** + * This class demonstrates how to create a BigQuery Extract Job and wait for it to complete. + * + * @see Jobs: insert + */ + private static class ExtractAction extends JobRunAction { + @Override + ExtractJobInfo parse(String... args) throws Exception { + if (args.length >= 4) { + String dataset = args[0]; + String table = args[1]; + String format = args[2]; + TableId tableId = TableId.of(dataset, table); + return ExtractJobInfo.builder(tableId, Arrays.asList(args).subList(3, args.length)) + .format(format) + .build(); + } + throw new IllegalArgumentException(); + } + + @Override + protected String params() { + return "
        +"; + } + } + + /** + * This class demonstrates how to create a BigQuery Copy Job and wait for it to complete. + * + * @see Jobs: insert + */ + private static class CopyAction extends JobRunAction { + @Override + CopyJobInfo parse(String... args) throws Exception { + if (args.length == 4) { + TableId sourceTableId = TableId.of(args[0], args[1]); + TableId destinationTableId = TableId.of(args[2], args[3]); + return CopyJobInfo.of(destinationTableId, sourceTableId); + } + throw new IllegalArgumentException(); + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to run a BigQuery SQL Query and wait for associated job to + * complete. Results or errors are shown. + * + * @see Jobs: query + */ + private static class QueryAction extends BigQueryAction { + @Override + void run(BigQuery bigquery, QueryRequest queryRequest) throws Exception { + System.out.println("Running query"); + QueryResponse queryResponse = bigquery.query(queryRequest); + while (!queryResponse.jobComplete()) { + System.out.println("Waiting for query job " + queryResponse.jobId() + " to complete"); + Thread.sleep(1000L); + queryResponse = bigquery.getQueryResults(queryResponse.jobId()); + } + if (!queryResponse.hasErrors()) { + System.out.println("Query succeeded. Results:"); + Iterator> iterator = queryResponse.result().iterateAll(); + while (iterator.hasNext()) { + System.out.println(iterator.next()); + } + } else { + System.out.println("Query completed with errors. Errors:"); + for (BigQueryError err : queryResponse.executionErrors()) { + System.out.println(err); + } + } + } + + @Override + QueryRequest parse(String... args) throws Exception { + if (args.length == 1) { + return QueryRequest.of(args[0]); + } + throw new IllegalArgumentException(); + } + + @Override + protected String params() { + return ""; + } + } + + static { + CREATE_ACTIONS.put("dataset", new CreateDatasetAction()); + CREATE_ACTIONS.put("table", new CreateSimpleTableAction()); + CREATE_ACTIONS.put("view", new CreateViewAction()); + CREATE_ACTIONS.put("external-table", new CreateExternalTableAction()); + INFO_ACTIONS.put("dataset", new DatasetInfoAction()); + INFO_ACTIONS.put("table", new TableInfoAction()); + INFO_ACTIONS.put("job", new JobInfoAction()); + LIST_ACTIONS.put("datasets", new ListDatasetsAction()); + LIST_ACTIONS.put("tables", new ListTablesAction()); + LIST_ACTIONS.put("jobs", new ListJobsAction()); + LIST_ACTIONS.put("data", new ListTableDataAction()); + DELETE_ACTIONS.put("dataset", new DeleteDatasetAction()); + DELETE_ACTIONS.put("table", new DeleteTableAction()); + ACTIONS.put("create", new ParentAction(CREATE_ACTIONS)); + ACTIONS.put("info", new ParentAction(INFO_ACTIONS)); + ACTIONS.put("list", new ParentAction(LIST_ACTIONS)); + ACTIONS.put("delete", new ParentAction(DELETE_ACTIONS)); + ACTIONS.put("cancel", new CancelJobAction()); + ACTIONS.put("load", new LoadAction()); + ACTIONS.put("extract", new ExtractAction()); + ACTIONS.put("copy", new CopyAction()); + ACTIONS.put("query", new QueryAction()); + } + + private static void printUsage() { + StringBuilder actionAndParams = new StringBuilder(); + for (Map.Entry entry : ACTIONS.entrySet()) { + actionAndParams.append("\n\t").append(entry.getKey()); + + String param = entry.getValue().params(); + if (param != null && !param.isEmpty()) { + actionAndParams.append(' ').append(param.replace("\n", "\n\t\t")); + } + } + System.out.printf("Usage: %s [] operation [entity] *%s%n", + BigQueryExample.class.getSimpleName(), actionAndParams); + } + + @SuppressWarnings("unchecked") + public static void main(String... args) throws Exception { + BigQueryOptions.Builder optionsBuilder = BigQueryOptions.builder(); + BigQueryAction action; + String actionName; + if (args.length >= 2 && !ACTIONS.containsKey(args[0])) { + actionName = args[1]; + optionsBuilder.projectId(args[0]); + action = ACTIONS.get(args[1]); + args = Arrays.copyOfRange(args, 2, args.length); + } else { + actionName = args[0]; + action = ACTIONS.get(args[0]); + args = Arrays.copyOfRange(args, 1, args.length); + } + if (action == null) { + System.out.println("Unrecognized action."); + printUsage(); + return; + } + BigQuery bigquery = optionsBuilder.build().service(); + Object request; + try { + request = action.parse(args); + } catch (IllegalArgumentException ex) { + System.out.println("Invalid input for action '" + actionName + "'"); + System.out.println("Expected: " + action.params()); + return; + } catch (Exception ex) { + System.out.println("Failed to parse request."); + ex.printStackTrace(); + return; + } + action.run(bigquery, request); + } +}