-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Peckstadt Yves <[email protected]>
- Loading branch information
1 parent
4afd222
commit 312512b
Showing
9 changed files
with
423 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
.../src/main/java/com/scalar/db/dataloader/core/dataimport/controlfile/ControlFileTable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package com.scalar.db.dataloader.core.dataimport.controlfile; | ||
|
||
import com.fasterxml.jackson.annotation.JsonCreator; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
/** | ||
* Represents the configuration for a single table in the control file, including its namespace, | ||
* table name, and field mappings. This class is used to define how data from a control file maps to | ||
* a specific table in ScalarDB. | ||
*/ | ||
@Getter | ||
@Setter | ||
public class ControlFileTable { | ||
|
||
/** The namespace of the table in ScalarDB. */ | ||
@JsonProperty("namespace") | ||
private String namespace; | ||
|
||
/** The name of the table in ScalarDB. */ | ||
@JsonProperty("table") | ||
private String table; | ||
|
||
/** | ||
* A list of mappings defining the correspondence between control file fields and table columns. | ||
*/ | ||
@JsonProperty("mappings") | ||
private final List<ControlFileTableFieldMapping> mappings; | ||
|
||
/** | ||
* Creates a new {@code ControlFileTable} instance with the specified namespace and table name. | ||
* The mappings list is initialized as an empty list. | ||
* | ||
* @param namespace The namespace of the table in ScalarDB. | ||
* @param table The name of the table in ScalarDB. | ||
*/ | ||
public ControlFileTable(String namespace, String table) { | ||
this.namespace = namespace; | ||
this.table = table; | ||
this.mappings = new ArrayList<>(); | ||
} | ||
|
||
/** | ||
* Constructs a {@code ControlFileTable} instance using data from a serialized JSON object. This | ||
* constructor is used for deserialization of API requests or control files. | ||
* | ||
* @param namespace The namespace of the table in ScalarDB. | ||
* @param table The name of the table in ScalarDB. | ||
* @param mappings A list of mappings that define the relationship between control file fields and | ||
* table columns. | ||
*/ | ||
@JsonCreator | ||
public ControlFileTable( | ||
@JsonProperty("namespace") String namespace, | ||
@JsonProperty("table") String table, | ||
@JsonProperty("mappings") List<ControlFileTableFieldMapping> mappings) { | ||
this.namespace = namespace; | ||
this.table = table; | ||
this.mappings = mappings; | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
...va/com/scalar/db/dataloader/core/dataimport/controlfile/ControlFileTableFieldMapping.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.scalar.db.dataloader.core.dataimport.controlfile; | ||
|
||
import com.fasterxml.jackson.annotation.JsonCreator; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
/** | ||
* Represents the mapping of a single field in the control file to a column in a ScalarDB table. | ||
* This class defines how data from a specific field in the input source should be mapped to the | ||
* corresponding column in the database. | ||
*/ | ||
@Getter | ||
@Setter | ||
public class ControlFileTableFieldMapping { | ||
|
||
/** The name of the field in the input source (e.g., JSON or CSV). */ | ||
@JsonProperty("source_field") | ||
private String sourceField; | ||
|
||
/** The name of the column in the ScalarDB table that the field maps to. */ | ||
@JsonProperty("target_column") | ||
private String targetColumn; | ||
|
||
/** | ||
* Constructs a {@code ControlFileTableFieldMapping} instance using data from a serialized JSON | ||
* object. This constructor is primarily used for deserialization of control file mappings. | ||
* | ||
* @param sourceField The name of the field in the input source (e.g., JSON or CSV). | ||
* @param targetColumn The name of the corresponding column in the ScalarDB table. | ||
*/ | ||
@JsonCreator | ||
public ControlFileTableFieldMapping( | ||
@JsonProperty("source_field") String sourceField, | ||
@JsonProperty("target_column") String targetColumn) { | ||
this.sourceField = sourceField; | ||
this.targetColumn = targetColumn; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
...ore/src/main/java/com/scalar/db/dataloader/core/tablemetadata/TableMetadataException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.scalar.db.dataloader.core.tablemetadata; | ||
|
||
/** A custom exception that encapsulates errors thrown by the TableMetaDataService */ | ||
public class TableMetadataException extends Exception { | ||
|
||
/** | ||
* Class constructor | ||
* | ||
* @param message error message | ||
* @param cause reason for exception | ||
*/ | ||
public TableMetadataException(String message, Throwable cause) { | ||
super(message, cause); | ||
} | ||
|
||
/** | ||
* Class constructor | ||
* | ||
* @param message error message | ||
*/ | ||
public TableMetadataException(String message) { | ||
super(message); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
.../core/src/main/java/com/scalar/db/dataloader/core/tablemetadata/TableMetadataRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.scalar.db.dataloader.core.tablemetadata; | ||
|
||
import lombok.Getter; | ||
|
||
/** Represents the request for metadata for a single ScalarDB table */ | ||
@Getter | ||
public class TableMetadataRequest { | ||
|
||
private final String namespace; | ||
private final String table; | ||
|
||
/** | ||
* Class constructor | ||
* | ||
* @param namespace ScalarDB namespace | ||
* @param table ScalarDB table name | ||
*/ | ||
public TableMetadataRequest(String namespace, String table) { | ||
this.namespace = namespace; | ||
this.table = table; | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
.../core/src/main/java/com/scalar/db/dataloader/core/tablemetadata/TableMetadataService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package com.scalar.db.dataloader.core.tablemetadata; | ||
|
||
import com.scalar.db.api.DistributedStorageAdmin; | ||
import com.scalar.db.api.TableMetadata; | ||
import com.scalar.db.common.error.CoreError; | ||
import com.scalar.db.dataloader.core.util.TableMetadataUtil; | ||
import com.scalar.db.exception.storage.ExecutionException; | ||
import java.util.Collection; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
/** | ||
* Service for retrieving {@link TableMetadata} from ScalarDB. Provides methods to fetch metadata | ||
* for individual tables or a collection of tables. | ||
*/ | ||
@RequiredArgsConstructor | ||
public class TableMetadataService { | ||
|
||
private final DistributedStorageAdmin storageAdmin; | ||
|
||
/** | ||
* Retrieves the {@link TableMetadata} for a specific namespace and table name. | ||
* | ||
* @param namespace The ScalarDB namespace. | ||
* @param tableName The name of the table within the specified namespace. | ||
* @return The {@link TableMetadata} object containing schema details of the specified table. | ||
* @throws TableMetadataException If the table or namespace does not exist, or if an error occurs | ||
* while fetching the metadata. | ||
*/ | ||
public TableMetadata getTableMetadata(String namespace, String tableName) | ||
throws TableMetadataException { | ||
try { | ||
TableMetadata tableMetadata = storageAdmin.getTableMetadata(namespace, tableName); | ||
if (tableMetadata == null) { | ||
throw new TableMetadataException( | ||
CoreError.DATA_LOADER_MISSING_NAMESPACE_OR_TABLE.buildMessage(namespace, tableName)); | ||
} | ||
return tableMetadata; | ||
} catch (ExecutionException e) { | ||
throw new TableMetadataException( | ||
CoreError.DATA_LOADER_TABLE_METADATA_RETRIEVAL_FAILED.buildMessage(e.getMessage()), e); | ||
} | ||
} | ||
|
||
/** | ||
* Retrieves the {@link TableMetadata} for a collection of table metadata requests. | ||
* | ||
* <p>Each request specifies a namespace and table name. The method consolidates the metadata into | ||
* a map keyed by a unique lookup key generated for each table. | ||
* | ||
* @param requests A collection of {@link TableMetadataRequest} objects specifying the tables to | ||
* retrieve metadata for. | ||
* @return A map where the keys are unique lookup keys (namespace + table name) and the values are | ||
* the corresponding {@link TableMetadata} objects. | ||
* @throws TableMetadataException If any of the requested tables or namespaces are missing, or if | ||
* an error occurs while fetching the metadata. | ||
*/ | ||
public Map<String, TableMetadata> getTableMetadata(Collection<TableMetadataRequest> requests) | ||
throws TableMetadataException { | ||
Map<String, TableMetadata> metadataMap = new HashMap<>(); | ||
|
||
for (TableMetadataRequest request : requests) { | ||
String namespace = request.getNamespace(); | ||
String tableName = request.getTable(); | ||
TableMetadata tableMetadata = getTableMetadata(namespace, tableName); | ||
String key = TableMetadataUtil.getTableLookupKey(namespace, tableName); | ||
metadataMap.put(key, tableMetadata); | ||
} | ||
|
||
return metadataMap; | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
data-loader/core/src/main/java/com/scalar/db/dataloader/core/util/TableMetadataUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package com.scalar.db.dataloader.core.util; | ||
|
||
import com.scalar.db.api.TableMetadata; | ||
import com.scalar.db.dataloader.core.Constants; | ||
import com.scalar.db.dataloader.core.dataimport.controlfile.ControlFileTable; | ||
import com.scalar.db.transaction.consensuscommit.Attribute; | ||
import com.scalar.db.transaction.consensuscommit.ConsensusCommitUtils; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
/** Utility class for handling ScalarDB table metadata operations. */ | ||
@NoArgsConstructor(access = AccessLevel.PRIVATE) | ||
public class TableMetadataUtil { | ||
|
||
/** | ||
* Generates a unique lookup key for a table within a namespace. | ||
* | ||
* @param namespace The namespace of the table. | ||
* @param tableName The name of the table. | ||
* @return A formatted string representing the table lookup key. | ||
*/ | ||
public static String getTableLookupKey(String namespace, String tableName) { | ||
return String.format(Constants.TABLE_LOOKUP_KEY_FORMAT, namespace, tableName); | ||
} | ||
|
||
/** | ||
* Generates a unique lookup key for a table using control file table data. | ||
* | ||
* @param controlFileTable The control file table object containing namespace and table name. | ||
* @return A formatted string representing the table lookup key. | ||
*/ | ||
public static String getTableLookupKey(ControlFileTable controlFileTable) { | ||
return String.format( | ||
Constants.TABLE_LOOKUP_KEY_FORMAT, | ||
controlFileTable.getNamespace(), | ||
controlFileTable.getTable()); | ||
} | ||
|
||
/** | ||
* Adds metadata columns to a list of projection columns for a ScalarDB table. | ||
* | ||
* @param tableMetadata The metadata of the ScalarDB table. | ||
* @param projections A list of projection column names. | ||
* @return A new list containing projection columns along with metadata columns. | ||
*/ | ||
public static List<String> populateProjectionsWithMetadata( | ||
TableMetadata tableMetadata, List<String> projections) { | ||
List<String> projectionMetadata = new ArrayList<>(); | ||
projections.forEach( | ||
projection -> { | ||
projectionMetadata.add(projection); | ||
if (!isKeyColumn(projection, tableMetadata)) { | ||
projectionMetadata.add(Attribute.BEFORE_PREFIX + projection); | ||
} | ||
}); | ||
projectionMetadata.addAll(ConsensusCommitUtils.getTransactionMetaColumns().keySet()); | ||
return projectionMetadata; | ||
} | ||
|
||
/** | ||
* Checks whether a column is a key column (partition key or clustering key) in the table. | ||
* | ||
* @param column The name of the column to check. | ||
* @param tableMetadata The metadata of the ScalarDB table. | ||
* @return {@code true} if the column is a key column; {@code false} otherwise. | ||
*/ | ||
private static boolean isKeyColumn(String column, TableMetadata tableMetadata) { | ||
return tableMetadata.getPartitionKeyNames().contains(column) | ||
|| tableMetadata.getClusteringKeyNames().contains(column); | ||
} | ||
} |
Oops, something went wrong.