Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.scalar.db.dataloader.cli.command.dataexport;

import static com.scalar.db.dataloader.cli.util.CommandLineInputUtils.validateDeprecatedOptionPair;
import static com.scalar.db.dataloader.cli.util.CommandLineInputUtils.validatePositiveValue;
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;
Expand Down Expand Up @@ -51,6 +52,8 @@ public class ExportCommand extends ExportCommandOptions implements Callable<Inte

@Override
public Integer call() throws Exception {
validateDeprecatedOptions();
applyDeprecatedOptions();
String scalarDbPropertiesFilePath = getScalarDbPropertiesFilePath();

try {
Expand Down Expand Up @@ -107,6 +110,24 @@ public Integer call() throws Exception {
return 0;
}

/**
* Validates that deprecated and new options are not both specified.
*
* @throws CommandLine.ParameterException if both old and new options are specified
*/
private void validateDeprecatedOptions() {
validateDeprecatedOptionPair(
spec.commandLine(),
DEPRECATED_START_EXCLUSIVE_OPTION,
START_INCLUSIVE_OPTION,
START_INCLUSIVE_OPTION_SHORT);
validateDeprecatedOptionPair(
spec.commandLine(),
DEPRECATED_END_EXCLUSIVE_OPTION,
END_INCLUSIVE_OPTION,
END_INCLUSIVE_OPTION_SHORT);
}

private String getScalarDbPropertiesFilePath() {
if (StringUtils.isBlank(configFilePath)) {
throw new IllegalArgumentException(DataLoaderError.CONFIG_FILE_PATH_BLANK.buildMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
public class ExportCommandOptions {

protected static final String DEFAULT_CONFIG_FILE_NAME = "scalardb.properties";
public static final String START_INCLUSIVE_OPTION = "--start-inclusive";
public static final String START_INCLUSIVE_OPTION_SHORT = "-si";
public static final String DEPRECATED_START_EXCLUSIVE_OPTION = "--start-exclusive";
public static final String END_INCLUSIVE_OPTION = "--end-inclusive";
public static final String END_INCLUSIVE_OPTION_SHORT = "-ei";
public static final String DEPRECATED_END_EXCLUSIVE_OPTION = "--end-exclusive";

@CommandLine.Option(
names = {"--config", "-c"},
Expand Down Expand Up @@ -87,6 +93,14 @@ public class ExportCommandOptions {
// TODO: test that -si false, works
protected boolean scanStartInclusive;

// Deprecated option - kept for backward compatibility
@CommandLine.Option(
names = {DEPRECATED_START_EXCLUSIVE_OPTION},
description = "Deprecated: Use --start-inclusive instead (inverted logic)",
hidden = true)
@Deprecated
protected Boolean startExclusiveDeprecated;

@CommandLine.Option(
names = {"--end-key", "-ek"},
paramLabel = "<KEY=VALUE>",
Expand All @@ -100,6 +114,14 @@ public class ExportCommandOptions {
defaultValue = "true")
protected boolean scanEndInclusive;

// Deprecated option - kept for backward compatibility
@CommandLine.Option(
names = {DEPRECATED_END_EXCLUSIVE_OPTION},
description = "Deprecated: Use --end-inclusive instead (inverted logic)",
hidden = true)
@Deprecated
protected Boolean endExclusiveDeprecated;

@CommandLine.Option(
names = {"--sort-by", "-s"},
paramLabel = "<SORT_ORDER>",
Expand Down Expand Up @@ -144,4 +166,23 @@ public class ExportCommandOptions {
description = "Size of the data chunk to process in a single task (default: 200)",
defaultValue = "200")
protected int dataChunkSize;

/**
* Applies deprecated option values if they are set.
*
* <p>This method is called AFTER validateDeprecatedOptions(), so we are guaranteed that both the
* deprecated and new options were not specified together. If we reach this point, only the
* deprecated option was provided by the user.
*/
public void applyDeprecatedOptions() {
// If the deprecated option is set, use its value (inverted logic)
if (startExclusiveDeprecated != null) {
scanStartInclusive = !startExclusiveDeprecated;
}

// If the deprecated option is set, use its value (inverted logic)
if (endExclusiveDeprecated != null) {
scanEndInclusive = !endExclusiveDeprecated;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.scalar.db.dataloader.cli.command.dataimport;

import static com.scalar.db.dataloader.cli.util.CommandLineInputUtils.validateDeprecatedOptionPair;
import static com.scalar.db.dataloader.cli.util.CommandLineInputUtils.validatePositiveValue;

import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -52,6 +53,8 @@ public class ImportCommand extends ImportCommandOptions implements Callable<Inte

@Override
public Integer call() throws Exception {
validateDeprecatedOptions();
applyDeprecatedOptions();
validateImportTarget(controlFilePath, namespace, tableName);
validateLogDirectory(logDirectory);
validatePositiveValue(
Expand Down Expand Up @@ -272,6 +275,19 @@ private Optional<ControlFile> parseControlFileFromPath(String controlFilePath) {
}
}

/**
* Validates that deprecated and new options are not both specified.
*
* @throws ParameterException if both old and new options are specified
*/
private void validateDeprecatedOptions() {
validateDeprecatedOptionPair(
spec.commandLine(),
DEPRECATED_THREADS_OPTION,
MAX_THREADS_OPTION,
MAX_THREADS_OPTION_SHORT);
}

/**
* Generate import options object from provided cli parameter data
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
public class ImportCommandOptions {

public static final String FILE_OPTION_NAME_LONG_FORMAT = "--file";
public static final String MAX_THREADS_OPTION = "--max-threads";
public static final String MAX_THREADS_OPTION_SHORT = "-mt";
public static final String DEPRECATED_THREADS_OPTION = "--threads";

@CommandLine.Option(
names = {"--mode", "-m"},
Expand Down Expand Up @@ -39,6 +42,15 @@ public class ImportCommandOptions {
defaultValue = "16")
protected int maxThreads;

// Deprecated option - kept for backward compatibility
@CommandLine.Option(
names = {DEPRECATED_THREADS_OPTION},
paramLabel = "<THREADS>",
description = "Deprecated: Use --max-threads instead",
Copy link
Contributor

@feeblefakie feeblefakie Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question, but why threads are renamed to max-threads?
It creates threads dynamically within the max, so that the number could be lower than the max depending on workloads?

hidden = true)
@Deprecated
protected Integer threadsDeprecated;

@CommandLine.Option(
names = {"--namespace", "-ns"},
paramLabel = "<NAMESPACE>",
Expand Down Expand Up @@ -158,4 +170,18 @@ public class ImportCommandOptions {
description = "Maximum number of data chunks that can be kept at a time for processing",
defaultValue = "256")
protected int dataChunkQueueSize;

/**
* Applies deprecated option values if they are set.
*
* <p>This method is called AFTER validateDeprecatedOptions(), so we are guaranteed that both the
* deprecated and new options were not specified together. If we reach this point, only the
* deprecated option was provided by the user.
*/
public void applyDeprecatedOptions() {
// If the deprecated option is set, use its value
if (threadsDeprecated != null) {
maxThreads = threadsDeprecated;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,30 @@ public static void validatePositiveValue(
throw new CommandLine.ParameterException(commandLine, error.buildMessage());
}
}

/**
* Validates that a deprecated option and its replacement are not both specified. If both options
* are detected, it throws a {@link picocli.CommandLine.ParameterException} with an appropriate
* error message.
*
* @param commandLine the {@link CommandLine} instance used to provide context for the exception
* @param deprecatedOption the deprecated option name
* @param newOption the new option name
* @param newOptionShort the short form of the new option name
* @throws CommandLine.ParameterException if both deprecated and new options are specified
*/
public static void validateDeprecatedOptionPair(
CommandLine commandLine, String deprecatedOption, String newOption, String newOptionShort) {
boolean hasDeprecated = commandLine.getParseResult().hasMatchedOption(deprecatedOption);
boolean hasNew =
commandLine.getParseResult().hasMatchedOption(newOption)
|| commandLine.getParseResult().hasMatchedOption(newOptionShort);

if (hasDeprecated && hasNew) {
throw new CommandLine.ParameterException(
commandLine,
DataLoaderError.DEPRECATED_AND_NEW_OPTION_BOTH_SPECIFIED.buildMessage(
deprecatedOption, newOption, newOption));
}
}
}
Loading