Skip to content

Commit 96ba8f0

Browse files
authored
Deprecate include-metadata option for data loader export (#3159)
1 parent a5284be commit 96ba8f0

File tree

19 files changed

+168
-175
lines changed

19 files changed

+168
-175
lines changed

data-loader/cli/src/main/java/com/scalar/db/dataloader/cli/command/dataexport/ExportCommand.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class ExportCommand extends ExportCommandOptions implements Callable<Inte
5555
public Integer call() throws Exception {
5656
validateDeprecatedOptions();
5757
applyDeprecatedOptions();
58+
warnAboutIgnoredDeprecatedOptions();
5859
String scalarDbPropertiesFilePath = getScalarDbPropertiesFilePath();
5960

6061
try {
@@ -141,6 +142,28 @@ private void validateDeprecatedOptions() {
141142
MAX_THREADS_OPTION_SHORT);
142143
}
143144

145+
/** Warns about deprecated options that are no longer used and have been completely ignored. */
146+
private void warnAboutIgnoredDeprecatedOptions() {
147+
CommandLine.ParseResult parseResult = spec.commandLine().getParseResult();
148+
boolean hasIncludeMetadata =
149+
parseResult.hasMatchedOption(DEPRECATED_INCLUDE_METADATA_OPTION)
150+
|| parseResult.hasMatchedOption(DEPRECATED_INCLUDE_METADATA_OPTION_SHORT);
151+
152+
if (hasIncludeMetadata) {
153+
// Use picocli's ANSI support for colored warning output
154+
CommandLine.Help.Ansi ansi = CommandLine.Help.Ansi.AUTO;
155+
String warning =
156+
ansi.string(
157+
"@|bold,yellow The "
158+
+ DEPRECATED_INCLUDE_METADATA_OPTION
159+
+ " option is deprecated and no longer has any effect. "
160+
+ "Use the 'scalar.db.consensus_commit.include_metadata.enabled' configuration property "
161+
+ "in your ScalarDB properties file to control whether transaction metadata is included in scan operations.|@");
162+
163+
logger.warn(warning);
164+
}
165+
}
166+
144167
private String getScalarDbPropertiesFilePath() {
145168
if (StringUtils.isBlank(configFilePath)) {
146169
throw new IllegalArgumentException(DataLoaderError.CONFIG_FILE_PATH_BLANK.buildMessage());
@@ -160,8 +183,7 @@ private void validateOutputDirectory() throws DirectoryValidationException {
160183

161184
private ExportManager createExportManager(
162185
TransactionFactory transactionFactory, ScalarDbDao scalarDbDao, FileFormat fileFormat) {
163-
ProducerTaskFactory taskFactory =
164-
new ProducerTaskFactory(delimiter, includeTransactionMetadata, prettyPrintJson);
186+
ProducerTaskFactory taskFactory = new ProducerTaskFactory(delimiter, prettyPrintJson);
165187
DistributedTransactionManager manager = transactionFactory.getTransactionManager();
166188
switch (fileFormat) {
167189
case JSON:
@@ -180,7 +202,6 @@ private ExportOptions buildExportOptions(Key partitionKey, ScanRange scanRange)
180202
ExportOptions.builder(namespace, table, partitionKey, outputFormat)
181203
.sortOrders(sortOrders)
182204
.excludeHeaderRow(excludeHeader)
183-
.includeTransactionMetadata(includeTransactionMetadata)
184205
.delimiter(delimiter)
185206
.limit(limit)
186207
.maxThreadCount(maxThreads)

data-loader/cli/src/main/java/com/scalar/db/dataloader/cli/command/dataexport/ExportCommandOptions.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public class ExportCommandOptions {
1919
public static final String MAX_THREADS_OPTION = "--max-threads";
2020
public static final String MAX_THREADS_OPTION_SHORT = "-mt";
2121
public static final String DEPRECATED_THREADS_OPTION = "--threads";
22+
public static final String DEPRECATED_INCLUDE_METADATA_OPTION = "--include-metadata";
23+
public static final String DEPRECATED_INCLUDE_METADATA_OPTION_SHORT = "-m";
2224

2325
@CommandLine.Option(
2426
names = {"--config", "-c"},
@@ -69,10 +71,19 @@ public class ExportCommandOptions {
6971
defaultValue = "json")
7072
protected FileFormat outputFormat;
7173

74+
/**
75+
* @deprecated As of release 3.17.0 This option is no longer used and will be removed in release
76+
* 4.0.0. The option is not fully removed as users who might already have their scripts or
77+
* commands pre-set might pass the argument and when passed if not supported, picocli will
78+
* throw an error. We want to avoid that and instead just show a warning.
79+
*/
80+
@Deprecated
7281
@CommandLine.Option(
7382
names = {"--include-metadata", "-m"},
74-
description = "Include transaction metadata in the exported data (default: false)",
75-
defaultValue = "false")
83+
description =
84+
"Deprecated: This option is no longer used. Please use scalar.db.consensus_commit.include_metadata.enabled to control whether transaction metadata is included in scan operations.",
85+
defaultValue = "false",
86+
hidden = true)
7687
protected boolean includeTransactionMetadata;
7788

7889
@CommandLine.Option(

data-loader/cli/src/test/java/com/scalar/db/dataloader/cli/command/dataexport/ExportCommandTest.java

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,14 @@ void call_withOnlyDeprecatedStartExclusive_shouldApplyInvertedValue() {
152152
cmd.parseArgs(args);
153153

154154
// Verify the deprecated value was parsed
155-
assertEquals(true, command.startExclusiveDeprecated);
155+
assertTrue(command.startExclusiveDeprecated);
156156

157157
// Apply deprecated options (this is what the command does after validation)
158158
command.applyDeprecatedOptions();
159159

160160
// Verify the value was applied with inverted logic
161161
// start-exclusive=true should become start-inclusive=false
162-
assertEquals(false, command.scanStartInclusive);
162+
assertFalse(command.scanStartInclusive);
163163
}
164164

165165
@Test
@@ -181,14 +181,14 @@ void call_withOnlyDeprecatedEndExclusive_shouldApplyInvertedValue() {
181181
cmd.parseArgs(args);
182182

183183
// Verify the deprecated value was parsed
184-
assertEquals(false, command.endExclusiveDeprecated);
184+
assertFalse(command.endExclusiveDeprecated);
185185

186186
// Apply deprecated options (this is what the command does after validation)
187187
command.applyDeprecatedOptions();
188188

189189
// Verify the value was applied with inverted logic
190190
// end-exclusive=false should become end-inclusive=true
191-
assertEquals(true, command.scanEndInclusive);
191+
assertTrue(command.scanEndInclusive);
192192
}
193193

194194
@Test
@@ -273,4 +273,83 @@ void call_withoutMaxThreads_shouldDefaultToAvailableProcessors() {
273273
// Verify it was set to available processors
274274
assertEquals(Runtime.getRuntime().availableProcessors(), command.maxThreads);
275275
}
276+
277+
@Test
278+
void call_withDeprecatedIncludeMetadataOption_shouldParseAndDetectOption() {
279+
// Test that the deprecated option can be parsed without crashing
280+
// and is detected for warning purposes (both long and short forms)
281+
String[] argsWithLongForm = {
282+
"--config",
283+
"scalardb.properties",
284+
"--namespace",
285+
"scalar",
286+
"--table",
287+
"asset",
288+
"--format",
289+
"JSON",
290+
"--include-metadata"
291+
};
292+
293+
String[] argsWithShortForm = {
294+
"--config",
295+
"scalardb.properties",
296+
"--namespace",
297+
"scalar",
298+
"--table",
299+
"asset",
300+
"--format",
301+
"JSON",
302+
"-m"
303+
};
304+
305+
// Test long form
306+
ExportCommand commandLong = new ExportCommand();
307+
CommandLine cmdLong = new CommandLine(commandLong);
308+
cmdLong.parseArgs(argsWithLongForm);
309+
commandLong.spec = cmdLong.getCommandSpec();
310+
311+
// Verify the option is detected (so warning will trigger)
312+
assertTrue(
313+
cmdLong
314+
.getParseResult()
315+
.hasMatchedOption(ExportCommandOptions.DEPRECATED_INCLUDE_METADATA_OPTION));
316+
317+
// Test short form
318+
ExportCommand commandShort = new ExportCommand();
319+
CommandLine cmdShort = new CommandLine(commandShort);
320+
cmdShort.parseArgs(argsWithShortForm);
321+
commandShort.spec = cmdShort.getCommandSpec();
322+
323+
// Verify the short option is detected (so warning will trigger)
324+
assertTrue(
325+
cmdShort
326+
.getParseResult()
327+
.hasMatchedOption(ExportCommandOptions.DEPRECATED_INCLUDE_METADATA_OPTION_SHORT));
328+
}
329+
330+
@Test
331+
void call_withoutDeprecatedIncludeMetadataOption_shouldNotDetectOption() {
332+
// Verify that when the deprecated option is NOT used, it's not detected
333+
// (so warning won't trigger incorrectly)
334+
String[] args = {
335+
"--config",
336+
"scalardb.properties",
337+
"--namespace",
338+
"scalar",
339+
"--table",
340+
"asset",
341+
"--format",
342+
"JSON"
343+
};
344+
345+
ExportCommand command = new ExportCommand();
346+
CommandLine cmd = new CommandLine(command);
347+
cmd.parseArgs(args);
348+
command.spec = cmd.getCommandSpec();
349+
350+
// Verify the option is NOT detected (so warning won't trigger)
351+
assertFalse(
352+
cmd.getParseResult()
353+
.hasMatchedOption(ExportCommandOptions.DEPRECATED_INCLUDE_METADATA_OPTION));
354+
}
276355
}

data-loader/core/src/main/java/com/scalar/db/dataloader/core/dataexport/CsvExportManager.java

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.scalar.db.dataloader.core.dataexport.producer.ProducerTaskFactory;
66
import com.scalar.db.dataloader.core.dataimport.dao.ScalarDbDao;
77
import com.scalar.db.dataloader.core.util.CsvUtil;
8-
import com.scalar.db.transaction.consensuscommit.ConsensusCommitUtils;
98
import java.io.IOException;
109
import java.io.Writer;
1110
import java.util.Iterator;
@@ -77,8 +76,7 @@ private String createCsvHeaderRow(ExportOptions exportOptions, TableMetadata tab
7776
Iterator<String> iterator = tableMetadata.getColumnNames().iterator();
7877
while (iterator.hasNext()) {
7978
String columnName = iterator.next();
80-
if (shouldIgnoreColumn(
81-
exportOptions.isIncludeTransactionMetadata(), columnName, tableMetadata, projections)) {
79+
if (!projections.isEmpty() && !projections.contains(columnName)) {
8280
continue;
8381
}
8482
headerRow.append(columnName);
@@ -90,24 +88,4 @@ private String createCsvHeaderRow(ExportOptions exportOptions, TableMetadata tab
9088
headerRow.append("\n");
9189
return headerRow.toString();
9290
}
93-
94-
/**
95-
* To ignore a column or not based on conditions such as if it is a metadata column or if it is
96-
* not include in selected projections
97-
*
98-
* @param isIncludeTransactionMetadata to include transaction metadata or not
99-
* @param columnName column name
100-
* @param tableMetadata table metadata
101-
* @param projections selected columns for projection
102-
* @return ignore the column or not
103-
*/
104-
private boolean shouldIgnoreColumn(
105-
boolean isIncludeTransactionMetadata,
106-
String columnName,
107-
TableMetadata tableMetadata,
108-
List<String> projections) {
109-
return (!isIncludeTransactionMetadata
110-
&& ConsensusCommitUtils.isTransactionMetaColumn(columnName, tableMetadata))
111-
|| (!projections.isEmpty() && !projections.contains(columnName));
112-
}
11391
}

data-loader/core/src/main/java/com/scalar/db/dataloader/core/dataexport/ExportManager.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import com.scalar.db.dataloader.core.dataexport.validation.ExportOptionsValidator;
1212
import com.scalar.db.dataloader.core.dataimport.dao.ScalarDbDao;
1313
import com.scalar.db.dataloader.core.dataimport.dao.ScalarDbDaoException;
14-
import com.scalar.db.dataloader.core.util.TableMetadataUtil;
1514
import com.scalar.db.exception.transaction.CrudException;
1615
import com.scalar.db.exception.transaction.UnknownTransactionStatusException;
1716
import com.scalar.db.io.DataType;
@@ -76,7 +75,6 @@ public ExportReport startExport(
7675
try {
7776
validateExportOptions(exportOptions, tableMetadata);
7877
Map<String, DataType> dataTypeByColumnName = tableMetadata.getColumnDataTypes();
79-
handleTransactionMetadata(exportOptions, tableMetadata);
8078
processHeader(exportOptions, tableMetadata, writer);
8179

8280
ExecutorService executorService =
@@ -198,22 +196,6 @@ private void validateExportOptions(ExportOptions exportOptions, TableMetadata ta
198196
ExportOptionsValidator.validate(exportOptions, tableMetadata);
199197
}
200198

201-
/**
202-
* To update projection columns of export options if include metadata options is enabled
203-
*
204-
* @param exportOptions export options
205-
* @param tableMetadata metadata of the table
206-
*/
207-
private void handleTransactionMetadata(ExportOptions exportOptions, TableMetadata tableMetadata) {
208-
if (exportOptions.isIncludeTransactionMetadata()
209-
&& !exportOptions.getProjectionColumns().isEmpty()) {
210-
List<String> projectionMetadata =
211-
TableMetadataUtil.populateProjectionsWithMetadata(
212-
tableMetadata, exportOptions.getProjectionColumns());
213-
exportOptions.setProjectionColumns(projectionMetadata);
214-
}
215-
}
216-
217199
/**
218200
* To create a scanner object
219201
*

data-loader/core/src/main/java/com/scalar/db/dataloader/core/dataexport/ExportOptions.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ public class ExportOptions {
2727
@Builder.Default private final int maxThreadCount = Runtime.getRuntime().availableProcessors();
2828
@Builder.Default private final String delimiter = ";";
2929
@Builder.Default private final boolean excludeHeaderRow = false;
30-
@Builder.Default private final boolean includeTransactionMetadata = false;
3130
@Builder.Default private List<String> projectionColumns = Collections.emptyList();
3231
private List<Scan.Ordering> sortOrders;
3332

data-loader/core/src/main/java/com/scalar/db/dataloader/core/dataexport/producer/CsvProducerTask.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.scalar.db.dataloader.core.util.CsvUtil;
77
import com.scalar.db.dataloader.core.util.DecimalUtil;
88
import com.scalar.db.io.DataType;
9-
import com.scalar.db.transaction.consensuscommit.ConsensusCommitUtils;
109
import java.nio.charset.Charset;
1110
import java.time.Instant;
1211
import java.time.LocalDate;
@@ -33,19 +32,17 @@ public class CsvProducerTask extends ProducerTask {
3332
/**
3433
* Class constructor
3534
*
36-
* @param includeMetadata Include metadata in the exported data
3735
* @param projectColumns list of columns that is required in export data
3836
* @param tableMetadata Metadata for a single ScalarDB table
3937
* @param columnDataTypes Map of data types for the all columns in a ScalarDB table
4038
* @param delimiter Delimiter used in csv content
4139
*/
4240
public CsvProducerTask(
43-
boolean includeMetadata,
4441
List<String> projectColumns,
4542
TableMetadata tableMetadata,
4643
Map<String, DataType> columnDataTypes,
4744
String delimiter) {
48-
super(includeMetadata, projectColumns, tableMetadata, columnDataTypes);
45+
super(projectColumns, tableMetadata, columnDataTypes);
4946
this.delimiter = delimiter;
5047
}
5148

@@ -82,12 +79,10 @@ private String convertResultToCsv(Result result) {
8279
while (iterator.hasNext()) {
8380
String columnName = iterator.next();
8481

85-
// Skip the field if it can be ignored based on check
82+
// Skip the field if it's not in the projection list (when projections are specified)
8683
boolean columnNotProjected =
8784
!projectedColumnsSet.isEmpty() && !projectedColumnsSet.contains(columnName);
88-
boolean isMetadataColumn =
89-
ConsensusCommitUtils.isTransactionMetaColumn(columnName, tableMetadata);
90-
if (columnNotProjected || (!includeMetadata && isMetadataColumn)) {
85+
if (columnNotProjected) {
9186
continue;
9287
}
9388

data-loader/core/src/main/java/com/scalar/db/dataloader/core/dataexport/producer/JsonLineProducerTask.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import com.scalar.db.api.TableMetadata;
77
import com.scalar.db.dataloader.core.DataLoaderObjectMapper;
88
import com.scalar.db.io.DataType;
9-
import com.scalar.db.transaction.consensuscommit.ConsensusCommitUtils;
109
import java.nio.charset.Charset;
1110
import java.time.Instant;
1211
import java.time.LocalDate;
@@ -28,17 +27,15 @@ public class JsonLineProducerTask extends ProducerTask {
2827
/**
2928
* Class constructor
3029
*
31-
* @param includeMetadata Include metadata in the exported data
3230
* @param projectionColumns list of columns that is required in export data
3331
* @param tableMetadata Metadata for a single ScalarDB table
3432
* @param columnDataTypes Map of data types for the all columns in a ScalarDB table
3533
*/
3634
public JsonLineProducerTask(
37-
boolean includeMetadata,
3835
List<String> projectionColumns,
3936
TableMetadata tableMetadata,
4037
Map<String, DataType> columnDataTypes) {
41-
super(includeMetadata, projectionColumns, tableMetadata, columnDataTypes);
38+
super(projectionColumns, tableMetadata, columnDataTypes);
4239
}
4340

4441
/**
@@ -72,12 +69,10 @@ private ObjectNode generateJsonForResult(Result result) {
7269

7370
// Loop through all the columns and to the json object
7471
for (String columnName : tableColumns) {
75-
// Skip the field if it can be ignored based on check
72+
// Skip the field if it's not in the projection list (when projections are specified)
7673
boolean columnNotProjected =
7774
!projectedColumnsSet.isEmpty() && !projectedColumnsSet.contains(columnName);
78-
boolean isMetadataColumn =
79-
ConsensusCommitUtils.isTransactionMetaColumn(columnName, tableMetadata);
80-
if (columnNotProjected || (!includeMetadata && isMetadataColumn)) {
75+
if (columnNotProjected) {
8176
continue;
8277
}
8378

0 commit comments

Comments
 (0)