diff --git a/src/main/java/bio/terra/cli/businessobject/resource/BqDataset.java b/src/main/java/bio/terra/cli/businessobject/resource/BqDataset.java index 7160ff80c..d04607390 100644 --- a/src/main/java/bio/terra/cli/businessobject/resource/BqDataset.java +++ b/src/main/java/bio/terra/cli/businessobject/resource/BqDataset.java @@ -23,13 +23,6 @@ */ public class BqDataset extends Resource { private static final Logger logger = LoggerFactory.getLogger(BqDataset.class); - /** - * Delimiter between the project id and dataset id for a BigQuery dataset. - * - *
The choice is somewhat arbitrary. BigQuery Datatsets do not have true URIs. The '.' - * delimiter allows the path to be used directly in SQL calls with a BigQuery extension. - */ - private static final char BQ_PROJECT_DATASET_DELIMITER = '.'; private String projectId; private String datasetId; @@ -164,7 +157,9 @@ public String resolve() { public String resolve(BqResolvedOptions resolveOption) { switch (resolveOption) { case FULL_PATH: - return projectId + BQ_PROJECT_DATASET_DELIMITER + datasetId; + return projectId + BqResolvedOptions.BQ_PROJECT_DELIMITER + datasetId; + case FULL_PATH_SQL: + return projectId + BqResolvedOptions.BQ_PROJECT_DELIMITER_SQL + datasetId; case DATASET_ID_ONLY: return datasetId; case PROJECT_ID_ONLY: diff --git a/src/main/java/bio/terra/cli/businessobject/resource/BqResolvedOptions.java b/src/main/java/bio/terra/cli/businessobject/resource/BqResolvedOptions.java index e764a6b09..b635180c9 100644 --- a/src/main/java/bio/terra/cli/businessobject/resource/BqResolvedOptions.java +++ b/src/main/java/bio/terra/cli/businessobject/resource/BqResolvedOptions.java @@ -2,16 +2,24 @@ /** This enum specifies the possible ways to resolve a BigQuery resource. */ public enum BqResolvedOptions { - FULL_PATH, // For data table: [project id].[dataset id].[data table id if applicable] + FULL_PATH, // For data table: [project id]:[dataset id].[data table id if applicable] + FULL_PATH_SQL, // For data table: [project id].[dataset id].[data table id if applicable] TABLE_ID_ONLY, // [data table id] DATASET_ID_ONLY, // [dataset id] PROJECT_ID_ONLY; // [project id] /** - * Delimiter between the project id, dataset id and/or data table id. - * - *
The choice is somewhat arbitrary. BigQuery datasets or tables do not have true URIs. The '.' - * delimiter allows the path to be used directly in SQL calls with a BigQuery extension. + * Delimiter between the project id and dataset id when using the command-line compatible + * identifier format. */ - public static final char BQ_PROJECT_DATA_TABLE_DELIMITER = '.'; + public static final char BQ_PROJECT_DELIMITER = ':'; + + /** + * Delimiter between the project id and dataset id when using the SQL-compatible identifier + * format. + */ + public static final char BQ_PROJECT_DELIMITER_SQL = '.'; + + /** Delimiter between the dataset ID and data table. */ + public static final char BQ_TABLE_DELIMITER = '.'; } diff --git a/src/main/java/bio/terra/cli/businessobject/resource/BqTable.java b/src/main/java/bio/terra/cli/businessobject/resource/BqTable.java index f6eb10c1f..bf7e370f4 100644 --- a/src/main/java/bio/terra/cli/businessobject/resource/BqTable.java +++ b/src/main/java/bio/terra/cli/businessobject/resource/BqTable.java @@ -1,7 +1,5 @@ package bio.terra.cli.businessobject.resource; -import static bio.terra.cli.businessobject.resource.BqResolvedOptions.BQ_PROJECT_DATA_TABLE_DELIMITER; - import bio.terra.cli.businessobject.Context; import bio.terra.cli.businessobject.Resource; import bio.terra.cli.serialization.persisted.resource.PDBqTable; @@ -133,9 +131,15 @@ public String resolve(BqResolvedOptions resolveOption) { switch (resolveOption) { case FULL_PATH: return projectId - + BQ_PROJECT_DATA_TABLE_DELIMITER + + BqResolvedOptions.BQ_PROJECT_DELIMITER + + datasetId + + BqResolvedOptions.BQ_TABLE_DELIMITER + + dataTableId; + case FULL_PATH_SQL: + return projectId + + BqResolvedOptions.BQ_PROJECT_DELIMITER_SQL + datasetId - + BQ_PROJECT_DATA_TABLE_DELIMITER + + BqResolvedOptions.BQ_TABLE_DELIMITER + dataTableId; case TABLE_ID_ONLY: return dataTableId; diff --git a/src/test/java/harness/utils/ExternalBQDatasets.java b/src/test/java/harness/utils/ExternalBQDatasets.java index 90f310674..e5eba5aef 100644 --- a/src/test/java/harness/utils/ExternalBQDatasets.java +++ b/src/test/java/harness/utils/ExternalBQDatasets.java @@ -217,14 +217,25 @@ public static BigQuery getBQClient(GoogleCredentials credentials) { .getService(); } - /** Gets cloud identifier for Dataset in full-path: [project id].[dataset id] */ + /** Gets cloud identifier for Dataset in full-path: [project id]:[dataset id] */ public static String getDatasetFullPath(String projectId, String datasetId) { + return projectId + ":" + datasetId; + } + + /** Gets cloud identifier for Dataset in full-path SQL: [project id].[dataset id] */ + public static String getDatasetFullPathSql(String projectId, String datasetId) { return projectId + "." + datasetId; } /** Gets cloud identifier for data table in full-path: [project id].[dataset id].[table id] */ public static String getDataTableFullPath( String projectId, String datasetId, String dataTableId) { + return projectId + ":" + datasetId + "." + dataTableId; + } + + /** Gets cloud identifier for data table in full-path: [project id].[dataset id].[table id] */ + public static String getDataTableFullPathSql( + String projectId, String datasetId, String dataTableId) { return projectId + "." + datasetId + "." + dataTableId; } diff --git a/src/test/java/unit/BqDatasetControlled.java b/src/test/java/unit/BqDatasetControlled.java index d8f5454b0..a65636ff7 100644 --- a/src/test/java/unit/BqDatasetControlled.java +++ b/src/test/java/unit/BqDatasetControlled.java @@ -221,9 +221,18 @@ void resolve() throws IOException { JSONObject resolved = TestCommand.runAndGetJsonObjectExpectSuccess("resource", "resolve", "--name=" + name); assertEquals( - workspace.googleProjectId + "." + datasetId, + workspace.googleProjectId + ":" + datasetId, resolved.get(name), - "default resolve includes [project id].[dataset id]"); + "default resolve includes [project id]:[dataset id]"); + + // `terra resource resolve --name=$name --format=json --bq-path=FULL_PATH_SQL` + JSONObject resolvedFullSql = + TestCommand.runAndGetJsonObjectExpectSuccess( + "resource", "resolve", "--name=" + name, "--bq-path=FULL_PATH_SQL"); + assertEquals( + workspace.googleProjectId + "." + datasetId, + resolvedFullSql.get(name), + "sql-compatible path includes [project id].[dataset id]"); // `terra resource resolve --name=$name --bq-path=PROJECT_ID_ONLY --format=json` JSONObject resolvedProjectIdOnly = diff --git a/src/test/java/unit/BqDatasetReferenced.java b/src/test/java/unit/BqDatasetReferenced.java index 287de3faf..cc90d7c3f 100644 --- a/src/test/java/unit/BqDatasetReferenced.java +++ b/src/test/java/unit/BqDatasetReferenced.java @@ -196,10 +196,18 @@ void resolve() throws IOException { JSONObject resolved = TestCommand.runAndGetJsonObjectExpectSuccess("resource", "resolve", "--name=" + name); assertEquals( - ExternalBQDatasets.getDatasetFullPath( - externalDataset.getProjectId(), externalDataset.getDatasetId()), + externalDataset.getProjectId() + ":" + externalDataset.getDatasetId(), resolved.get(name), - "default resolve includes [project id].[dataset id]"); + "default resolve includes [project id]:[dataset id]"); + + // `terra resource resolve --name=$name --bq-path=PROJECT_ID_ONLY --format=json` + JSONObject resolvedFullPathSql = + TestCommand.runAndGetJsonObjectExpectSuccess( + "resource", "resolve", "--name=" + name, "--bq-path=FULL_PATH_SQL"); + assertEquals( + externalDataset.getProjectId() + "." + externalDataset.getDatasetId(), + resolvedFullPathSql.get(name), + "resolve with FULL_PATH_SQL includes [project id].[dataset id]"); // `terra resource resolve --name=$name --bq-path=PROJECT_ID_ONLY --format=json` JSONObject resolvedProjectIdOnly = diff --git a/src/test/java/unit/BqTableReferenced.java b/src/test/java/unit/BqTableReferenced.java index 5b9568ad9..b616a274b 100644 --- a/src/test/java/unit/BqTableReferenced.java +++ b/src/test/java/unit/BqTableReferenced.java @@ -260,10 +260,26 @@ void resolve() throws IOException { JSONObject resolved = TestCommand.runAndGetJsonObjectExpectSuccess("resource", "resolve", "--name=" + name); assertEquals( - ExternalBQDatasets.getDataTableFullPath( - externalDataset.getProjectId(), externalDataset.getDatasetId(), externalDataTableName), + externalDataset.getProjectId() + + ":" + + externalDataset.getDatasetId() + + "." + + externalDataTableName, resolved.get(name), - "default resolve include full path"); + "default resolve includes full path"); + + // `terra resource resolve --name=$name --format=json --bq-path=FULL_PATH_SQL` + JSONObject resolvedFullPathSql = + TestCommand.runAndGetJsonObjectExpectSuccess( + "resource", "resolve", "--name=" + name, "--bq-path=FULL_PATH_SQL"); + assertEquals( + externalDataset.getProjectId() + + "." + + externalDataset.getDatasetId() + + "." + + externalDataTableName, + resolvedFullPathSql.get(name), + "sql-compatible resolve includes SQL delimeter"); // `terra resource resolve --name=$name --bq-path=PROJECT_ID_ONLY --format=json` JSONObject resolvedProjectIdOnly =