-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add data loader core key and column utils #1771
base: master
Are you sure you want to change the base?
Conversation
data-loader/core/src/main/java/com/scalar/db/dataloader/core/util/KeyUtils.java
Show resolved
Hide resolved
DataType columnDataType = tableMetadata.getColumnDataType(columnName); | ||
if (columnDataType == null) { | ||
throw new KeyParsingException( | ||
CoreError.DATA_LOADER_INVALID_COLUMN_KEY_PARSING_FAILED.buildMessage(columnName)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering what if there are 3 tables that have name
column and this exception is thrown for the second table. Users may want to know which table...? What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the method and now passing in the table name as well. I had to add it because the table name is not part of the TableMetadata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ypeckstadt Thanks for improving the error message!
But, sorry, I should've noticed this when posting the previous comment, other error messages (e.g., DATA_LOADER_INVALID_COLUMN_NON_EXISTENT) have the same issue. Also, the namespace name should be added as well. I think we have 2 options as follows:
- Add namespace and table names to all the error messages if needed
- The class is a util class for keys, so it may be okay to include only key name in the error messages from
KeyUtils
. Instead, we'll catch exceptions fromKeyUtils
and wrap it with the namespace and table names like this:
try {
:
// This exception doesn't contain the namespace or table name.
Key key = KeyUtils.parseKeyValue(columnKeyValue, tableMetadata);
} catch (KeyParsingException e) {
// Add the namespace and table names information.
throw new KeyParsingException(
CoreError.DATA_LOADER_XXXX_FAILED.buildMessage(namespaceName, tableName), e);
}
I think either is fine. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have made changes based on the above feedback. I went for option 1 as it seems like the safest solution. Option 2 is good as well, but then it shifts the responsibility for proper exception handling and logging to all classes that use the Key Utils. So it creates the risk that some classes do it and some don't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the improvement!
It looks like there is room to improve the other error messages from the same perspective (i.e., missing information about namespace and table). What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@komamitsu My apologies for the late reply. (had to focus on ScalarFlow more). I have updated the PR and ensured each exception message includes the namespace and table name.
To avoid having to pass in all 3 with all methods, I have added a wrapper class called ColumnInfo
that includes all 3 fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left several minor comments. Please take a look when you have time!
* @return ScalarDB column | ||
* @throws Base64Exception if an error occurs while base64 decoding | ||
*/ | ||
public static Column<?> createColumnFromValue(DataType dataType, String columnName, String value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding @Nullable
for nullable parameters would be helpful:
public static Column<?> createColumnFromValue(DataType dataType, String columnName, String value) | |
public static Column<?> createColumnFromValue(DataType dataType, String columnName, @Nullable String value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
} catch (NumberFormatException e) { | ||
throw new NumberFormatException( | ||
CoreError.DATA_LOADER_INVALID_NUMBER_FORMAT_FOR_COLUMN_VALUE.buildMessage(columnName)); | ||
} catch (IllegalArgumentException e) { | ||
throw new Base64Exception( | ||
CoreError.DATA_LOADER_INVALID_BASE64_ENCODING_FOR_COLUMN_VALUE.buildMessage(columnName)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should set the cause of the exceptions:
} catch (NumberFormatException e) { | |
throw new NumberFormatException( | |
CoreError.DATA_LOADER_INVALID_NUMBER_FORMAT_FOR_COLUMN_VALUE.buildMessage(columnName)); | |
} catch (IllegalArgumentException e) { | |
throw new Base64Exception( | |
CoreError.DATA_LOADER_INVALID_BASE64_ENCODING_FOR_COLUMN_VALUE.buildMessage(columnName)); | |
} | |
} catch (NumberFormatException e) { | |
throw new NumberFormatException( | |
CoreError.DATA_LOADER_INVALID_NUMBER_FORMAT_FOR_COLUMN_VALUE.buildMessage(columnName), e); | |
} catch (IllegalArgumentException e) { | |
throw new Base64Exception( | |
CoreError.DATA_LOADER_INVALID_BASE64_ENCODING_FOR_COLUMN_VALUE.buildMessage(columnName), e); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added. Although to fix this I had to revise the used exceptions a bit.
throw new KeyParsingException( | ||
CoreError.DATA_LOADER_INVALID_VALUE_KEY_PARSING_FAILED.buildMessage( | ||
columnKeyValue.getColumnValue(), tableName, e.getMessage())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
throw new KeyParsingException( | |
CoreError.DATA_LOADER_INVALID_VALUE_KEY_PARSING_FAILED.buildMessage( | |
columnKeyValue.getColumnValue(), tableName, e.getMessage())); | |
throw new KeyParsingException( | |
CoreError.DATA_LOADER_INVALID_VALUE_KEY_PARSING_FAILED.buildMessage( | |
columnKeyValue.getColumnValue(), tableName, e.getMessage()), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you!
"Invalid key: Column %s does not exist in the table %s in namespace %s.", | ||
"", | ||
""), | ||
DATA_LOADER_INVALID_VALUE_KEY_PARSING_FAILED( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to be used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. It has become unused due to refactoring the error handling based on Toshi's feedback. I have removed it now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left several very minor comments. Other than that, LGTM! Thank you!
@@ -1,9 +1,11 @@ | |||
subprojects { | |||
group = "scalardb.dataloader" | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary empty line?
@@ -23,5 +25,12 @@ subprojects { | |||
testImplementation "org.mockito:mockito-core:${mockitoVersion}" | |||
testImplementation "org.mockito:mockito-inline:${mockitoVersion}" | |||
testImplementation "org.mockito:mockito-junit-jupiter:${mockitoVersion}" | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto. Unnecessary empty line?
Description
Later in the code for the export and import managers, we need a lot of utils that help us deal with working and converting ScalarDB keys and columns. This PR adds the basic version of the utils class, allowing us to convert keys based on CLI input in the following PR. More methods will be added to these utils later.
Related issues and/or PRs
This PR depends on the following PRs and should be reviewed once merged.
Changes made
Checklist
Additional notes (optional)
NA
Release notes
NA