Skip to content

Commit

Permalink
Add CatalogTableIdentifier interface
Browse files Browse the repository at this point in the history
  • Loading branch information
vinishjail97 committed Dec 24, 2024
1 parent 1d09924 commit 8c3724b
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,93 +18,8 @@

package org.apache.xtable.model.catalog;

import lombok.Getter;
import lombok.NonNull;

/**
* An internal representation of a fully qualified table identifier within a catalog. The naming
* convention varies across different catalogs but many of them follow a three level hierarchy, few
* examples can be found below.
*
* <ul>
* <li>1. catalog.database.table
* <li>2. catalog.schema.table
* <li>3. database.schema.table
* </ul>
*
* We have selected the first naming convention and will interoperate among other catalogs following
* a different convention.
*/
@Getter
public class CatalogTableIdentifier {
/**
* The top level hierarchy/namespace for organizing tables. Each catalog can have multiple
* databases/schemas. This is an optional field as many catalogs have a "default" catalog whose
* name varies depending on the catalogType.
*/
String catalogName;
/**
* Catalogs have the ability to group tables logically, databaseName is the identifier for such
* logical classification. The alternate names for this field include namespace, schemaName etc.
*/
@NonNull String databaseName;

/**
* The table name used when syncing the table to the catalog. NOTE: This name can be different
* from the table name in storage.
*/
@NonNull String tableName;

public CatalogTableIdentifier(
String catalogName, @NonNull String databaseName, @NonNull String tableName) {
this.catalogName = catalogName;
this.databaseName = databaseName;
this.tableName = tableName;
}

// 2. Use constructor chaining for the two-argument constructor
public CatalogTableIdentifier(String databaseName, String tableName) {
this(null, databaseName, tableName); // calls the above constructor with catalogName = null
}

/**
* Constructs a new {@code CatalogTableIdentifier} from a hierarchical string identifier.
*
* <p>The identifier is expected to be in one of the following formats:
*
* <ul>
* <li>{@code database.table} (two parts, no catalog)
* <li>{@code catalog.database.table} (three parts)
* </ul>
*
* If the identifier does not match one of these formats, an {@link IllegalArgumentException} is
* thrown.
*
* @param hierarchicalTableIdentifier The hierarchical string identifier (e.g.,
* "myCatalog.myDatabase.myTable" or "myDatabase.myTable").
* @throws IllegalArgumentException If the provided string does not match a valid two-part or
* three-part identifier.
*/
public CatalogTableIdentifier(String hierarchicalTableIdentifier) {
String[] parts = hierarchicalTableIdentifier.split("\\.");
if (parts.length == 2) {
this.catalogName = null;
this.databaseName = parts[0];
this.tableName = parts[1];
} else if (parts.length == 3) {
this.catalogName = parts[0];
this.databaseName = parts[1];
this.tableName = parts[2];
} else {
throw new IllegalArgumentException("Invalid table identifier " + hierarchicalTableIdentifier);
}
}

@Override
public String toString() {
if (catalogName != null && !catalogName.isEmpty()) {
return catalogName + "." + databaseName + "." + tableName;
}
return databaseName + "." + tableName;
}
/** Represents a catalog table identifier in a multi-level catalog system. */
public interface CatalogTableIdentifier {
/** Returns the string identifier for the table within its catalog context */
String getId();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.xtable.model.catalog;

import lombok.Getter;
import lombok.NonNull;

/**
* An internal representation of a fully qualified table identifier within a catalog. The naming
* convention varies across different catalogs but many of them follow a three level hierarchy, few
* examples can be found below.
*
* <ul>
* <li>1. catalog.database.table
* <li>2. catalog.schema.table
* <li>3. database.schema.table
* </ul>
*
* We have selected the first naming convention and will interoperate among other catalogs following
* a different convention.
*/
@Getter
public class HierarchicalTableIdentifier implements CatalogTableIdentifier {
/**
* The top level hierarchy/namespace for organizing tables. Each catalog can have multiple
* databases/schemas. This is an optional field as many catalogs have a "default" catalog whose
* name varies depending on the catalogType.
*/
String catalogName;
/**
* Catalogs have the ability to group tables logically, databaseName is the identifier for such
* logical classification. The alternate names for this field include namespace, schemaName etc.
*/
@NonNull String databaseName;

/**
* The table name used when syncing the table to the catalog. NOTE: This name can be different
* from the table name in storage.
*/
@NonNull String tableName;

public HierarchicalTableIdentifier(
String catalogName, @NonNull String databaseName, @NonNull String tableName) {
this.catalogName = catalogName;
this.databaseName = databaseName;
this.tableName = tableName;
}

public HierarchicalTableIdentifier(String databaseName, String tableName) {
this(null, databaseName, tableName);
}

/**
* Constructs a new {@code CatalogTableIdentifier} from a hierarchical string identifier.
*
* <p>The identifier is expected to be in one of the following formats:
*
* <ul>
* <li>{@code database.table} (two parts, no catalog)
* <li>{@code catalog.database.table} (three parts)
* </ul>
*
* If the identifier does not match one of these formats, an {@link IllegalArgumentException} is
* thrown.
*
* @param hierarchicalTableIdentifier The hierarchical string identifier (e.g.,
* "myCatalog.myDatabase.myTable" or "myDatabase.myTable").
* @throws IllegalArgumentException If the provided string does not match a valid two-part or
* three-part identifier.
*/
public HierarchicalTableIdentifier(String hierarchicalTableIdentifier) {
String[] parts = hierarchicalTableIdentifier.split("\\.");
if (parts.length == 2) {
this.catalogName = null;
this.databaseName = parts[0];
this.tableName = parts[1];
} else if (parts.length == 3) {
this.catalogName = parts[0];
this.databaseName = parts[1];
this.tableName = parts[2];
} else {
throw new IllegalArgumentException("Invalid table identifier " + hierarchicalTableIdentifier);
}
}

@Override
public String getId() {
if (catalogName != null && !catalogName.isEmpty()) {
return catalogName + "." + databaseName + "." + tableName;
}
return databaseName + "." + tableName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
package org.apache.xtable.spi.extractor;

import org.apache.xtable.conversion.SourceTable;
import org.apache.xtable.model.catalog.CatalogTableIdentifier;
import org.apache.xtable.model.catalog.HierarchicalTableIdentifier;

/**
* A client for converting the table with tableIdentifier {@link CatalogTableIdentifier} in source
* catalog to SourceTable object {@link SourceTable}, can be used by downstream consumers for
* A client for converting the table with tableIdentifier {@link HierarchicalTableIdentifier} in
* source catalog to SourceTable object {@link SourceTable}, can be used by downstream consumers for
* syncing it to multiple {@link org.apache.xtable.conversion.TargetTable}
*/
public interface CatalogConversionSource {
/** Returns the source table object present in the catalog. */
SourceTable getSourceTable(CatalogTableIdentifier tableIdentifier);
SourceTable getSourceTable(HierarchicalTableIdentifier tableIdentifier);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import org.apache.commons.lang3.StringUtils;

import org.apache.xtable.model.InternalTable;
import org.apache.xtable.model.catalog.CatalogTableIdentifier;
import org.apache.xtable.model.catalog.HierarchicalTableIdentifier;
import org.apache.xtable.model.sync.SyncResult;
import org.apache.xtable.model.sync.SyncResult.CatalogSyncStatus;

Expand All @@ -48,7 +48,7 @@ public static CatalogSync getInstance() {
}

public SyncResult syncTable(
Map<CatalogTableIdentifier, CatalogSyncClient> catalogSyncClients, InternalTable table) {
Map<HierarchicalTableIdentifier, CatalogSyncClient> catalogSyncClients, InternalTable table) {
List<CatalogSyncStatus> results = new ArrayList<>();
Instant startTime = Instant.now();
catalogSyncClients.forEach(
Expand Down Expand Up @@ -81,7 +81,7 @@ public SyncResult syncTable(

private <TABLE> CatalogSyncStatus syncCatalog(
CatalogSyncClient<TABLE> catalogSyncClient,
CatalogTableIdentifier tableIdentifier,
HierarchicalTableIdentifier tableIdentifier,
InternalTable table) {
if (!catalogSyncClient.hasDatabase(tableIdentifier.getDatabaseName())) {
catalogSyncClient.createDatabase(tableIdentifier.getDatabaseName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class TestCatalogTableIdentifier {
class TestHierarchicalTableIdentifier {

@Test
void testToString() {
CatalogTableIdentifier catalogTableIdentifier =
new CatalogTableIdentifier("catalogName.databaseName.tableName");
HierarchicalTableIdentifier catalogTableIdentifier =
new HierarchicalTableIdentifier("catalogName.databaseName.tableName");
assertEquals("catalogName.databaseName.tableName", catalogTableIdentifier.toString());
}

@Test
void testConstructorForHierarchicalTableIdentifier() {
Assertions.assertDoesNotThrow(
() -> new CatalogTableIdentifier("catalogName.databaseName.tableName"));
Assertions.assertDoesNotThrow(() -> new CatalogTableIdentifier("databaseName.tableName"));
() -> new HierarchicalTableIdentifier("catalogName.databaseName.tableName"));
Assertions.assertDoesNotThrow(() -> new HierarchicalTableIdentifier("databaseName.tableName"));
Assertions.assertThrows(
IllegalArgumentException.class, () -> new CatalogTableIdentifier("tableName"));
IllegalArgumentException.class, () -> new HierarchicalTableIdentifier("tableName"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import com.google.common.collect.ImmutableMap;

import org.apache.xtable.model.InternalTable;
import org.apache.xtable.model.catalog.CatalogTableIdentifier;
import org.apache.xtable.model.catalog.HierarchicalTableIdentifier;
import org.apache.xtable.model.schema.InternalField;
import org.apache.xtable.model.schema.InternalPartitionField;
import org.apache.xtable.model.schema.InternalSchema;
Expand All @@ -55,14 +55,14 @@ public class TestCatalogSync<TABLE> {
@Mock CatalogSyncClient<TABLE> mockClient3;
@Mock CatalogSyncClient<TABLE> mockClient4;

private final CatalogTableIdentifier tableIdentifier1 =
new CatalogTableIdentifier("database1", "table1");
private final CatalogTableIdentifier tableIdentifier2 =
new CatalogTableIdentifier("database2", "table2");
private final CatalogTableIdentifier tableIdentifier3 =
new CatalogTableIdentifier("database3", "table3");
private final CatalogTableIdentifier tableIdentifier4 =
new CatalogTableIdentifier("database4", "table4");
private final HierarchicalTableIdentifier tableIdentifier1 =
new HierarchicalTableIdentifier("database1", "table1");
private final HierarchicalTableIdentifier tableIdentifier2 =
new HierarchicalTableIdentifier("database2", "table2");
private final HierarchicalTableIdentifier tableIdentifier3 =
new HierarchicalTableIdentifier("database3", "table3");
private final HierarchicalTableIdentifier tableIdentifier4 =
new HierarchicalTableIdentifier("database4", "table4");

@Mock TABLE mockTable;
private final InternalTable internalTable =
Expand Down Expand Up @@ -96,7 +96,7 @@ void testSyncTable() {

when(mockClient4.getCatalogId()).thenReturn("catalogId4");

Map<CatalogTableIdentifier, CatalogSyncClient> catalogSyncClients =
Map<HierarchicalTableIdentifier, CatalogSyncClient> catalogSyncClients =
ImmutableMap.of(
tableIdentifier1, mockClient1,
tableIdentifier2, mockClient2,
Expand Down

0 comments on commit 8c3724b

Please sign in to comment.