From c85609a73b463dc1d04ee9cabcfb02ce92ec8ab5 Mon Sep 17 00:00:00 2001 From: Ben Yu Date: Sun, 3 Dec 2023 15:30:09 -0800 Subject: [PATCH] Expand on the BigQuery ParameterizedQuery javadoc --- .../mu/bigquery/ParameterizedQuery.java | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/mug-bigquery/src/main/java/com/google/mu/bigquery/ParameterizedQuery.java b/mug-bigquery/src/main/java/com/google/mu/bigquery/ParameterizedQuery.java index 31fe8e9f04..3586d88909 100644 --- a/mug-bigquery/src/main/java/com/google/mu/bigquery/ParameterizedQuery.java +++ b/mug-bigquery/src/main/java/com/google/mu/bigquery/ParameterizedQuery.java @@ -27,11 +27,54 @@ import com.google.mu.util.stream.BiStream; /** - * Facade class to create BigQuery parameterized queries using a template string and parameters. + * Facade class to create + * BigQuery parameterized queries using a template string and parameters. * - *

The string template syntax is defined by {@link StringFormat} and protected by the same + *

The string template syntax is defined by {@link StringFormat} and protected by the same set of * compile-time checks. * + *

For simple use cases, a one-liner is enough to construct a parameterized query. For example: + * + *

{@code
+ * ParameterizedQuery query = ParameterizedQuery.of(
+ *     "SELECT name FROM Students WHERE id = {id} and status = {status}",
+ *     studentId, Status.ENROLLED);
+ * TableResult result = query.run();
+ * }
+ * + *

If you need to reuse the same query for different parameters, or to get a long query + * "out of the way", you can define the query template as a class constant: + * + *

{@code
+ * private static final StringFormat.To GET_STUDENT = ParameterizedQuery.template(
+ *     "SELECT name FROM Students WHERE id = {id} and status = {status}");
+ *
+ * // 200 lines later
+ * TableResult enrolled = GET_STUDENT.with(studentId, Status.ENROLLED).run();
+ * TableResult graduated = GET_STUDENT.with(alumniId, Status.GRADUATED).run();
+ * }
+ * + * Compared to building the {@link QueryJobConfiguration} object manually, you get the following benefits: + * + * + *

In addition to parameterizing by values, you can also parameterize by columns, table names or + * sub-queries. The following example allows you to use the same query on different datasets: + * + *

{@code
+ * private static final StringFormat.To GET_TABLES = ParameterizedQuery.template(
+ *     "SELECT table_name FROM `{dataset}.INFORMATION_SCHEMA.TABLES`");
+ *
+ * TableResult marketingTables = GET_TABLES.with(ParameterizedQuery.of("marketing")).run();
+ * TableResult humanResourceTables = GET_TABLES.with(ParameterizedQuery.of("human-resource")).run();
+ * }
+ * + * Non-value string parameters must be wrapped inside {@code ParameterizedQuery} to ensure safety. + * * @since 7.1 */ @Immutable @@ -95,6 +138,7 @@ public static ParameterizedQuery of(@CompileTimeConstant String query, Object... *
  • BigDecimal *
  • Double *
  • Float + *
  • arrays * * * If you need to supply other types, consider to wrap them explicitly using one of the static @@ -142,7 +186,7 @@ public static StringFormat.To template(@CompileTimeConstant * your choice. */ public TableResult run(JobOption... options) throws JobException, InterruptedException { - return BigQueryOptions.getDefaultInstance().getService().query(jobConfiguration()); + return BigQueryOptions.getDefaultInstance().getService().query(jobConfiguration(), options); } /** Returns the {@link QueryJobConfiguration} that can be sent to BigQuery. */