Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e661698
Consolidate Dataclass data update methods - use DIB for update only
XingY Mar 10, 2026
09dd6b0
Enable upgrade script
XingY Mar 10, 2026
b5e2ac2
CRLF
XingY Mar 10, 2026
dc19ef1
Merge remote-tracking branch 'origin/develop' into fb_sourceDIB
XingY Mar 10, 2026
4d9ff01
fix build
XingY Mar 11, 2026
a678378
merge from develop
XingY Mar 11, 2026
a68e8a8
fix merge
XingY Mar 11, 2026
9d5aa75
fix merge
XingY Mar 11, 2026
4893660
fix update
XingY Mar 12, 2026
4b5e0ef
Merge remote-tracking branch 'origin/develop' into fb_sourceDIB
XingY Mar 15, 2026
d3aea2b
Merge remote-tracking branch 'origin/develop' into fb_sourceDIB
XingY Mar 23, 2026
44f7811
merge from develop
XingY Apr 6, 2026
a35f233
fix attachment
XingY Apr 7, 2026
28142df
Merge remote-tracking branch 'origin/develop' into fb_sourceDIB
XingY Apr 20, 2026
04f83ff
Fix alias in audit
XingY Apr 21, 2026
3446ba4
don't check for fail fast for DataClassUpdateAddColumnsDataIterator
XingY Apr 21, 2026
2a91cc6
Merge remote-tracking branch 'origin/develop' into fb_sourceDIB
XingY Apr 21, 2026
312a13c
Make sample consistent with data for failfast
XingY Apr 22, 2026
60898fa
Fix reclassify
XingY Apr 23, 2026
988d5fd
fix folder import
XingY Apr 23, 2026
22745ed
Merge remote-tracking branch 'origin/develop' into fb_sourceDIB
XingY Apr 23, 2026
e07508c
Remove `altUpdateKeys` from `QueryInfo`
XingY Apr 24, 2026
896c5cb
CC review
XingY Apr 24, 2026
53b876f
revert null values
XingY Apr 24, 2026
edca844
crlf
XingY Apr 24, 2026
3080753
Merge remote-tracking branch 'origin/develop' into fb_sourceDIB
XingY Apr 24, 2026
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
3 changes: 2 additions & 1 deletion api/src/org/labkey/api/exp/api/ExperimentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ public interface ExperimentService extends ExperimentRunTypeSource

String EXPERIMENTAL_FEATURE_FROM_EXPANCESTORS = "org.labkey.api.exp.api.ExperimentService#FROM_EXPANCESTORS";

String EXPERIMENTAL_FEATURE_ALLOW_ROW_ID_MERGE = "org.labkey.experiment.api.SampleTypeUpdateServiceDI#ALLOW_ROW_ID_SAMPLE_MERGE";

int SIMPLE_PROTOCOL_FIRST_STEP_SEQUENCE = 1;
int SIMPLE_PROTOCOL_CORE_STEP_SEQUENCE = 10;
int SIMPLE_PROTOCOL_EXTRA_STEP_SEQUENCE = 15;
Expand All @@ -149,7 +151,6 @@ static void setInstance(ExperimentService impl)

enum QueryOptions
{
UseLsidForUpdate,
GetSampleRecomputeCol,
SkipBulkRemapCache,
DeferRequiredLineageValidation,
Expand Down
57 changes: 31 additions & 26 deletions api/src/org/labkey/api/exp/query/ExpDataTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,47 @@ public interface ExpDataTable extends ExpTable<ExpDataTable.Column>
{
enum Column
{
RowId,
Alias,
ContentLink,
ClassId, // database table only
CpasType, // database table only
Created,
CreatedBy,
DataClass,
DataFileUrl,
Description,
DownloadLink,
FileExtension,
FileExists,
FileSize,
Flag,
Folder,
Generated,
InlineThumbnail,
Inputs,
LastIndexed,
LSID,
Modified,
ModifiedBy,
Name,
Description,
DataClass,
ObjectId, // database table only
Outputs,
Properties,
Protocol,
SourceProtocolApplication,
SourceApplicationInput,
DataFileUrl,
ReferenceCount,
Run,
RunApplication,
RunApplicationOutput,
Created,
CreatedBy,
Modified,
ModifiedBy,
Folder,
Flag,
Alias,
DownloadLink,
ContentLink,
ViewFileLink,
RunId, // database table only
RowId,
SourceApplicationId, // database table only
SourceApplicationInput,
SourceProtocolApplication,
Thumbnail,
InlineThumbnail,
FileSize,
FileExists,
FileExtension,
ViewFileLink,
ViewOrDownload,
WebDavUrl,
WebDavUrlRelative,
Generated,
LastIndexed,
Inputs,
Outputs,
Properties;
WebDavUrlRelative;

public FieldKey fieldKey()
{
Expand Down
102 changes: 102 additions & 0 deletions api/src/org/labkey/api/query/AbstractQueryUpdateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.labkey.api.query;

import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -122,6 +123,8 @@
import static org.labkey.api.audit.TransactionAuditProvider.DB_SEQUENCE_NAME;
import static org.labkey.api.dataiterator.DetailedAuditLogDataIterator.AuditConfigs.AuditBehavior;
import static org.labkey.api.dataiterator.DetailedAuditLogDataIterator.AuditConfigs.AuditUserComment;
import static org.labkey.api.exp.query.ExpMaterialTable.Column.Name;
import static org.labkey.api.exp.query.ExpMaterialTable.Column.RowId;
import static org.labkey.api.files.FileContentService.UPLOADED_FILE;
import static org.labkey.api.util.FileUtil.toFileForRead;
import static org.labkey.api.util.FileUtil.toFileForWrite;
Expand Down Expand Up @@ -453,6 +456,9 @@ protected int _pump(DataIteratorBuilder etl, final @Nullable ArrayList<Map<Strin
{
DataIterator it = etl.getDataIterator(context);

if (null == it)
return 0;

try
{
if (null != rows)
Expand Down Expand Up @@ -900,6 +906,102 @@ public List<Map<String, Object>> updateRows(User user, Container container, List
return result;
}

protected void validatePartitionedRowKeys(Collection<String> columns)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Provide a description for this method that describes its purpose/intent.

{
// do nothing
}

public List<Map<String, Object>> updateRowsUsingPartitionedDIB(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

  1. Make this protected
  2. Provide a description of this method.

DbScope.Transaction tx,
User user,
Container container,
List<Map<String, Object>> rows,
BatchValidationException errors,
@Nullable Map<Enum, Object> configParameters,
Map<String, Object> extraScriptContext
)
{
int index = 0;
int numPartitions = 0;
List<Map<String, Object>> ret = new ArrayList<>();

Set<Long> observedRowIds = new HashSet<>();
Set<String> observedNames = new CaseInsensitiveHashSet();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Abstraction is leaking a bit here. If some other structure (e.g., Lists) were to use this it doesn't support "Name" in the same way data classes and sample types do.


while (index < rows.size())
{
CaseInsensitiveHashSet rowKeys = new CaseInsensitiveHashSet(rows.get(index).keySet());

validatePartitionedRowKeys(rowKeys);

int nextIndex = index + 1;
while (nextIndex < rows.size() && rowKeys.equals(new CaseInsensitiveHashSet(rows.get(nextIndex).keySet())))
nextIndex++;

List<Map<String, Object>> rowsToProcess = rows.subList(index, nextIndex);
index = nextIndex;
numPartitions++;

DataIteratorContext context = getDataIteratorContext(errors, InsertOption.UPDATE, configParameters);

// skip audit summary for the partitions, we will perform it once at the end
context.putConfigParameter(ConfigParameters.SkipAuditSummary, true);

List<Map<String, Object>> subRet = _updateRowsUsingDIB(user, container, rowsToProcess, context, extraScriptContext);

// we need to throw if we don't want executeWithRetry() attempt commit()
if (context.getErrors().hasErrors())
throw new DbScope.RetryPassthroughException(context.getErrors());

if (subRet != null)
{
ret.addAll(subRet);

// Check if duplicate rows have been processed across the partitions
// Only start checking for duplicates after the first partition has been processed.
if (numPartitions > 1)
{
// If we are on the second partition, then lazily check all previous rows, otherwise check only the current partition
checkPartitionForDuplicates(numPartitions == 2 ? ret : subRet, observedRowIds, observedNames, errors);
}

if (errors.hasErrors())
throw new DbScope.RetryPassthroughException(errors);
}
}

if (numPartitions > 1)
{
var auditEvent = tx.getAuditEvent();
if (auditEvent != null)
auditEvent.addDetail(TransactionAuditProvider.TransactionDetail.DataIteratorPartitions, numPartitions);
}

_addSummaryAuditEvent(container, user, getDataIteratorContext(errors, InsertOption.UPDATE, configParameters), ret.size());

return ret;
}

private void checkPartitionForDuplicates(List<Map<String, Object>> partitionRows, Set<Long> globalRowIds, Set<String> globalNames, BatchValidationException errors)
{
for (Map<String, Object> row : partitionRows)
{
Long rowId = MapUtils.getLong(row, RowId.name());
if (rowId != null && !globalRowIds.add(rowId))
{
errors.addRowError(new ValidationException("Duplicate key provided: " + rowId));
return;
}

Object nameObj = row.get(Name.name());
if (nameObj != null && !globalNames.add(nameObj.toString()))
{
errors.addRowError(new ValidationException("Duplicate key provided: " + nameObj));
return;
}
}
}

protected void checkDuplicateUpdate(Object pkVals) throws ValidationException
{
if (pkVals == null)
Expand Down
7 changes: 1 addition & 6 deletions api/src/org/labkey/api/query/DefaultQueryUpdateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -778,14 +778,9 @@ protected boolean validMissingValue(Container c, String mv)
return _missingValues.containsKey(mv);
}

protected TableInfo getTableInfoForConversion()
{
return getDbTable();
}

final protected void convertTypes(User user, Container c, Map<String,Object> row) throws ValidationException
{
convertTypes(user, c, row, getTableInfoForConversion(), null);
convertTypes(user, c, row, getDbTable(), null);
}

// TODO Path->FileObject
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT core.executeJavaUpgradeCode('dropProvisionedDataClassLsidColumn');
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EXEC core.executeJavaUpgradeCode 'dropProvisionedDataClassLsidColumn';
Loading