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
11 changes: 0 additions & 11 deletions api/src/org/labkey/api/dataiterator/DataIteratorContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public class DataIteratorContext
LookupResolutionType _lookupResolutionType = LookupResolutionType.primaryKey;
QueryImportPipelineJob _backgroundJob = null;
boolean _crossTypeImport = false;
boolean _crossFolderImport = false;
boolean _allowCreateStorage = false;
boolean _useTransactionAuditCache = false;
private final Set<String> _passThroughBuiltInColumnNames = new CaseInsensitiveHashSet();
Expand Down Expand Up @@ -202,16 +201,6 @@ public void setCrossTypeImport(boolean crossTypeImport)
_crossTypeImport = crossTypeImport;
}

public boolean isCrossFolderImport()
{
return _crossFolderImport;
}

public void setCrossFolderImport(boolean crossFolderImport)
{
_crossFolderImport = crossFolderImport;
}

public boolean isAllowCreateStorage()
{
return _allowCreateStorage;
Expand Down
6 changes: 0 additions & 6 deletions api/src/org/labkey/api/query/AbstractQueryImportAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ public enum Params
crossTypeImport,
allowCreateStorage,
importLookupByAlternateKey, // deprecated. Prefer lookupResolutionType
crossFolderImport,
useTransactionAuditCache,
lookupResolutionType,
auditDetails,
Expand All @@ -331,7 +330,6 @@ protected Map<Params, Boolean> getOptionParamsMap()
_optionParamsMap.put(Params.importIdentity, Boolean.valueOf(getParam(Params.importIdentity)));
_optionParamsMap.put(Params.crossTypeImport, Boolean.valueOf(getParam(Params.crossTypeImport)));
_optionParamsMap.put(Params.allowCreateStorage, Boolean.valueOf(getParam(Params.allowCreateStorage)));
_optionParamsMap.put(Params.crossFolderImport, Boolean.valueOf(getParam(Params.crossFolderImport)));
_optionParamsMap.put(Params.useTransactionAuditCache, Boolean.valueOf(getParam(Params.useTransactionAuditCache)));
}
return _optionParamsMap;
Expand All @@ -345,8 +343,6 @@ protected Set<String> getTransactionImportParams(String insertOption, boolean us
importParams.add("backgroundImport");
if (Boolean.valueOf(getParam(Params.crossTypeImport)))
importParams.add(Params.crossTypeImport.name());
if (Boolean.valueOf(getParam(Params.crossFolderImport)))
importParams.add(Params.crossFolderImport.name());
if (Boolean.valueOf(getParam(Params.useTransactionAuditCache)))
importParams.add(Params.useTransactionAuditCache.name());
if (Boolean.valueOf(getParam(Params.allowCreateStorage)))
Expand Down Expand Up @@ -852,7 +848,6 @@ public static DataIteratorContext createDataIteratorContext(QueryUpdateService.I
boolean importIdentity = optionParamsMap.getOrDefault(AbstractQueryImportAction.Params.importIdentity, false);
boolean crossTypeImport = optionParamsMap.getOrDefault(AbstractQueryImportAction.Params.crossTypeImport, false);
boolean allowCreateStorage = optionParamsMap.getOrDefault(AbstractQueryImportAction.Params.allowCreateStorage, false);
boolean crossFolderImport = optionParamsMap.getOrDefault(AbstractQueryImportAction.Params.crossFolderImport, false);
boolean useTransactionAuditCache = optionParamsMap.getOrDefault(Params.useTransactionAuditCache, false);

DataIteratorContext context = new DataIteratorContext(errors);
Expand All @@ -874,7 +869,6 @@ public static DataIteratorContext createDataIteratorContext(QueryUpdateService.I
context.setSupportAutoIncrementKey(true);
}
context.setCrossTypeImport(crossTypeImport);
context.setCrossFolderImport(crossFolderImport && container != null && container.hasProductFolders());
context.setAllowCreateStorage(allowCreateStorage);
context.setUseTransactionAuditCache(useTransactionAuditCache);
context.setLogger(logger);
Expand Down
16 changes: 6 additions & 10 deletions api/src/org/labkey/api/query/AbstractQueryUpdateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ public Map<Integer, Map<String, Object>> getExistingRows(User user, Container co
Map<Integer, Map<String, Object>> result = new LinkedHashMap<>();
for (Map.Entry<Integer, Map<String, Object>> key : keys.entrySet())
{
String keyDisplay = key.getValue().toString();

Map<String, Object> row = getRow(user, container, key.getValue(), verifyNoCrossFolderData);
if (row != null && !row.isEmpty())
{
Expand All @@ -215,21 +217,15 @@ public Map<Integer, Map<String, Object>> getExistingRows(User user, Container co
if (StringUtils.isEmpty(dataContainer))
dataContainer = (String) row.get("folder");
if (!container.getId().equals(dataContainer))
throw new InvalidKeyException("Data does not belong to folder '" + container.getName() + "': " + key.getValue().values());
throw new InvalidKeyException("Data does not exist in " + container.getName() + ": " + keyDisplay + ".");
}
}
else if (verifyExisting)
throw new InvalidKeyException("Data not found for " + key.getValue().values());
throw new InvalidKeyException("Data does not exist in " + container.getName() + ": " + keyDisplay + ".");
}
return result;
}

@Override
public boolean hasExistingRowsInOtherContainers(Container container, Map<Integer, Map<String, Object>> keys)
{
return false;
}

public static TransactionAuditProvider.TransactionAuditEvent createTransactionAuditEvent(Container container, QueryService.AuditAction auditAction)
{
return createTransactionAuditEvent(container, auditAction, null);
Expand Down Expand Up @@ -408,7 +404,7 @@ protected int _importRowsUsingDIB(User user, Container container, DataIteratorBu

preImportDIBValidation(in, null);

boolean skipTriggers = context.getConfigParameterBoolean(ConfigParameters.SkipTriggers) || context.isCrossTypeImport() || context.isCrossFolderImport();
boolean skipTriggers = context.getConfigParameterBoolean(ConfigParameters.SkipTriggers) || context.isCrossTypeImport();
boolean hasTableScript = hasTableScript(container);
TriggerDataBuilderHelper helper = new TriggerDataBuilderHelper(getQueryTable(), container, user, extraScriptContext, context.getInsertOption().useImportAliases);
if (!skipTriggers)
Expand Down Expand Up @@ -1299,7 +1295,7 @@ static FileLike checkFileUnderRoot(Container container, FileLike file) throws Ex

protected void _addSummaryAuditEvent(Container container, User user, DataIteratorContext context, int count)
{
if (!context.isCrossTypeImport() && !context.isCrossFolderImport()) // audit handled at table level
if (!context.isCrossTypeImport()) // audit handled at table level
{
AuditBehaviorType auditType = (AuditBehaviorType) context.getConfigParameter(DetailedAuditLogDataIterator.AuditConfigs.AuditBehavior);
String auditUserComment = (String) context.getConfigParameter(DetailedAuditLogDataIterator.AuditConfigs.AuditUserComment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,6 @@ public List<Map<String, Object>> getRows(User user, Container container, List<Ma
return _service.getRows(user, container, keys);
}

@Override
public boolean hasExistingRowsInOtherContainers(Container container, Map<Integer, Map<String, Object>> keys)
{
var ret = _service.hasExistingRowsInOtherContainers(container, keys);
clearCache();
return ret;
}

@Override
public Map<Integer, Map<String, Object>> getExistingRows(User user, Container container, Map<Integer, Map<String, Object>> keys, boolean verifyNoCrossFolderData, boolean verifyExisting, Set<String> columns)
throws InvalidKeyException, QueryUpdateServiceException, SQLException
Expand Down
19 changes: 0 additions & 19 deletions api/src/org/labkey/api/query/DefaultQueryUpdateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -915,25 +915,6 @@ protected boolean isAttachmentProperty(String name)
return false;
}

protected void configureCrossFolderImport(DataIteratorBuilder rows, DataIteratorContext context) throws IOException
{
if (!context.getInsertOption().updateOnly && context.isCrossFolderImport() && rows instanceof DataLoader dataLoader)
{
boolean hasContainerField = false;
for (ColumnDescriptor columnDescriptor : dataLoader.getColumns())
{
String fieldName = columnDescriptor.getColumnName();
if (fieldName.equalsIgnoreCase("Container") || fieldName.equalsIgnoreCase("Folder"))
{
hasContainerField = true;
break;
}
}
if (!hasContainerField)
context.setCrossFolderImport(false);
}
}

public static @Nullable String getKeyColumnAliasForUpdate(TableInfo tableInfo, @NotNull Map<String, Integer> columnNameMap)
{
// Currently, SampleUpdateAddColumnsDataIterator and DataClassUpdateAddColumnsDataIterator is being called before a translator is invoked to
Expand Down
2 changes: 0 additions & 2 deletions api/src/org/labkey/api/query/QueryUpdateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ List<Map<String, Object>> getRows(User user, Container container, List<Map<Strin
Map<Integer, Map<String, Object>> getExistingRows(User user, Container container, Map<Integer, Map<String, Object>> keys, boolean verifyNoCrossFolderData, boolean verifyExisting, @Nullable Set<String> columns)
throws InvalidKeyException, QueryUpdateServiceException, SQLException;

boolean hasExistingRowsInOtherContainers(Container container, Map<Integer, Map<String, Object>> keys);

/**
* Inserts or merges the given values into the source table of this query.
* The operation to be performed and import behavior is configured by the <code>context</code> parameter.
Expand Down
8 changes: 4 additions & 4 deletions experiment/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion experiment/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"devDependencies": {
"@labkey/build": "9.1.4",
"@labkey/test": "1.13.2",
"@labkey/test": "1.14.0-fb-dropCrossFolder.1",
"@types/jest": "30.0.0",
"@types/react": "18.3.27",
"@types/react-dom": "18.3.7",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hookServer, RequestOptions, selectRandomN, successfulResponse } from '@labkey/test';
import { hookServer, RequestOptions, selectRandomN, successfulResponse, testSeed } from '@labkey/test';

import {
deleteAssayDesign,
Expand All @@ -12,7 +12,8 @@ import { ASSAY_DESIGNER_ROLE } from '@labkey/components';

// @ts-expect-error process is not available in a browser environment
const server = hookServer(process.env);
const PROJECT_NAME = 'DataClassCrudJestProject';
const PROJECT_NAME = 'AssayDesignCrudJestProject';
console.log(`[AssayDesignCrud] Random seed: ${testSeed} (rerun with: TEST_SEED=${testSeed})`);

let readerUser, readerUserOptions;
let editorUser, editorUserOptions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hookServer, IntegrationTestServer, RequestOptions, successfulResponse } from '@labkey/test';
import { hookServer, IntegrationTestServer, RequestOptions, successfulResponse, testSeed } from '@labkey/test';
import mock from 'mock-fs';

import {
Expand Down Expand Up @@ -27,6 +27,9 @@ import {
// @ts-expect-error process is not available in a browser environment
const server = hookServer(process.env);
const PROJECT_NAME = 'ArrayImportRunActionTest Project';

console.log(`[ArrayImportRunAction] Random seed: ${testSeed} (rerun with: TEST_SEED=${testSeed})`);

const BATCH_FILE_FIELD_NAME = 'batchFileField';
const BATCH_FILE_FIELD_TWO_NAME = 'batchFile2Field';
const RUN_FILE_FIELD_NAME = 'runFileField';
Expand Down
15 changes: 8 additions & 7 deletions experiment/src/client/test/integration/DataClassCrud.ispec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
getEscapedNameExpression,
hookServer,
RequestOptions,
successfulResponse
successfulResponse,
testSeed
} from '@labkey/test';
import mock from 'mock-fs';
import {
Expand All @@ -22,6 +23,7 @@ import {
import { caseInsensitive, DATA_CLASS_DESIGNER_ROLE } from '@labkey/components';
const server = hookServer(process.env);
const PROJECT_NAME = 'DataClassCrudJestProject';
console.log(`[DataClassCrud] Random seed: ${testSeed} (rerun with: TEST_SEED=${testSeed})`);

let readerUser, readerUserOptions;
let editorUser, editorUserOptions;
Expand Down Expand Up @@ -278,8 +280,7 @@ describe('Import with update / merge', () => {
it ("Issue 52922: Blank sample id in the file are getting ignored in update from file", async () => {
const BLANK_KEY_UPDATE_ERROR_NO_EXPRESSION = 'Missing value for required property: Name';
const BLANK_KEY_UPDATE_ERROR_WITH_EXPRESSION = 'Name value not provided on row ';
const BOGUS_KEY_UPDATE_ERROR = 'Data not found for ';
const DUPLICATE_KEY_ERROR = 'duplicate key value';
const BOGUS_KEY_UPDATE_ERROR = 'Data does not exist in ';

const dataType = "NoExpressionNameRequired52922";
const createPayload = {
Expand Down Expand Up @@ -349,9 +350,9 @@ describe('Import with update / merge', () => {
successResp = await ExperimentCRUDUtils.importData(server, "Name\tDescription\n\tisBlank", dataTypeWithExpression, "MERGE", subfolder1Options, editorUserOptions);
expect(successResp.text.indexOf('"success" : true') > -1).toBeTruthy();

// cross folder update not supported when folder type is "Collaboration"
// cross folder update not supported
let crossFolderErrorResp = await ExperimentCRUDUtils.importData(server, "Name\tDescription\nData1\tNotblank\n\tisBlank", dataTypeWithExpression, "MERGE", subfolder1Options, editorUserOptions);
expect(crossFolderErrorResp.text.indexOf(DUPLICATE_KEY_ERROR) > -1).toBeTruthy();
expect(crossFolderErrorResp.text.indexOf(BOGUS_KEY_UPDATE_ERROR) > -1).toBeTruthy();
crossFolderErrorResp = await ExperimentCRUDUtils.importData(server, "Name\tDescription\nData1\tNotblank", dataTypeWithExpression, "UPDATE", subfolder1Options, editorUserOptions);
expect(crossFolderErrorResp.text.indexOf(BOGUS_KEY_UPDATE_ERROR) > -1).toBeTruthy();

Expand Down Expand Up @@ -1140,12 +1141,12 @@ describe('Data CRUD', () => {
}]
}, { ...topFolderOptions, ...editorUserOptions }).expect((result) => {
const errorResp = JSON.parse(result.text);
expect(errorResp['exception']).toContain('Data not found for [' + row3RowId + ']');
expect(errorResp['exception']).toContain('Data does not exist in ' + PROJECT_NAME + ': {RowId=' + row3RowId + '}.');
});

// using update from file, verify update using rowId for data that doesn't exist on this dataclass should fail.
errorResp = await ExperimentCRUDUtils.importData(server, "RowId\tDescription\n" + row3RowId + "\tupdate\n", emptyDataClass, "UPDATE", topFolderOptions, editorUserOptions);
expect(errorResp.text).toContain('Data not found for [' + row3RowId + ']');
expect(errorResp.text).toContain('Data does not exist in ' + PROJECT_NAME + ': {RowId=' + row3RowId + '}.');

});

Expand Down
22 changes: 15 additions & 7 deletions experiment/src/client/test/integration/SampleTypeCrud.ispec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { ExperimentCRUDUtils, hookServer, RequestOptions, selectRandomN, successfulResponse } from '@labkey/test';
import {
ExperimentCRUDUtils,
hookServer,
RequestOptions,
selectRandomN,
successfulResponse,
testSeed
} from '@labkey/test';
import mock from 'mock-fs';
import {
checkDomainName,
Expand All @@ -15,6 +22,8 @@ const { importSample, insertRows } = ExperimentCRUDUtils;
const server = hookServer(process.env);
const PROJECT_NAME = 'SampleTypeCrudJestProject';

console.log(`[SampleTypeCrud] Random seed: ${testSeed} (rerun with: TEST_SEED=${testSeed})`);

const SAMPLE_ALIQUOT_IMPORT_TYPE_NAME = "SampleType_Aliquots_Import";
const SAMPLE_ALIQUOT_REQ_IMPORT_TYPE_NAME = "Aliquot_Import_RequiredProp";
const SAMPLE_ALIQUOT_IMPORT_NO_NAME_PATTERN_NAME = "SampleType_Aliquots_Import_NoExpression";
Expand Down Expand Up @@ -318,8 +327,7 @@ describe('Import with update / merge', () => {
it ("Issue 52922: Blank sample id in the file are getting ignored in update from file", async () => {
const BLANK_KEY_UPDATE_ERROR = 'Name value not provided';
const BLANK_KEY_MERGE_ERROR_NO_EXPRESSION = 'SampleID or Name is required for sample';
const BOGUS_KEY_UPDATE_ERROR = 'Sample does not exist: bogus.';
const CROSS_FOLDER_UPDATE_NOT_SUPPORTED_ERROR = "Sample does not belong to ";
const BOGUS_KEY_UPDATE_ERROR = 'Sample does not exist in ';

const dataType = SAMPLE_ALIQUOT_IMPORT_NO_NAME_PATTERN_NAME;
const dataName = "Data1";
Expand Down Expand Up @@ -369,11 +377,11 @@ describe('Import with update / merge', () => {
successResp = await ExperimentCRUDUtils.importSample(server, "Name\tDescription\n\tisBlank", dataTypeWithExpression, "MERGE", subfolder1Options, editorUserOptions);
expect(successResp.text.indexOf('"success" : true') > -1).toBeTruthy();

// cross folder update not supported when folder type is "Collaboration"
// cross folder update not supported
let crossFolderUpdateErrorResp = await ExperimentCRUDUtils.importSample(server, "Name\tDescription\nData1\tNotblank", dataTypeWithExpression, "UPDATE", subfolder1Options, editorUserOptions);
expect(crossFolderUpdateErrorResp.text.indexOf(CROSS_FOLDER_UPDATE_NOT_SUPPORTED_ERROR) > -1).toBeTruthy();
expect(crossFolderUpdateErrorResp.text.indexOf(BOGUS_KEY_UPDATE_ERROR) > -1).toBeTruthy();
let crossFolderMergeErrorResp = await ExperimentCRUDUtils.importSample(server, "Name\tDescription\nData1\tNotblank\n\tisBlank", dataTypeWithExpression, "MERGE", subfolder1Options, editorUserOptions);
expect(crossFolderMergeErrorResp.text.indexOf(CROSS_FOLDER_UPDATE_NOT_SUPPORTED_ERROR) > -1).toBeTruthy();
expect(crossFolderMergeErrorResp.text.indexOf(BOGUS_KEY_UPDATE_ERROR) > -1).toBeTruthy();

// bogus name
bogusKeyProvidedError = await ExperimentCRUDUtils.importSample(server, "Name\tDescription\nbogus\tisBogus", dataTypeWithExpression, "UPDATE", topFolderOptions, editorUserOptions);
Expand Down Expand Up @@ -487,7 +495,7 @@ describe('Import with update / merge', () => {
// Assert
// Verify that these rows are not updated
expect(resp.body.success).toEqual(false);
expect(resp.body.exception).toContain('Sample does not exist: (RowId)');
expect(resp.body.exception).toContain('Sample does not exist in ' + PROJECT_NAME + ': (RowId)');
})
});

Expand Down
3 changes: 2 additions & 1 deletion experiment/src/client/test/integration/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
ExperimentCRUDUtils,
generateFieldName,
IntegrationTestServer,
random,
RequestOptions,
selectRandomN,
successfulResponse,
Expand Down Expand Up @@ -632,7 +633,7 @@ export async function verifyRequiredLineageInsertUpdate(server: IntegrationTestS
const dataType = "withRequired" + (isParentSample ? 'SampleParent' : 'DataParent');
let childDomainId = -1, childDomainURI = '';

const useLowerCase = Math.random() < 0.5;
const useLowerCase = random() < 0.5;
// test both lower case and upper case prefix
const parentInput = (isParentSample ? (useLowerCase ? 'materialInputs/' : 'MaterialInputs/') : (useLowerCase ? 'dataInputs/' : 'DataInputs/')) + parentDataType;
await server.post('property', 'createDomain', {
Expand Down
Loading