diff --git a/api/src/org/labkey/api/action/QueryViewAction.java b/api/src/org/labkey/api/action/QueryViewAction.java
index 9ebb9540eac..42a02c7bae6 100644
--- a/api/src/org/labkey/api/action/QueryViewAction.java
+++ b/api/src/org/labkey/api/action/QueryViewAction.java
@@ -16,6 +16,7 @@
package org.labkey.api.action;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.labkey.api.data.ColumnHeaderType;
import org.labkey.api.data.ExcelWriter;
@@ -135,7 +136,9 @@ protected ModelAndView getHtmlView(Form form, BindException errors) throws Excep
/**
* Correctly configures the QueryView to use the QueryViewAction for export purposes
* @param dataRegion null as a convenience when only a single QueryView is being used
+ * @throws NotFoundException if passed a dataRegion name that doesn't exist
*/
+ @NotNull
protected final ViewType createInitializedQueryView(Form form, BindException errors, boolean forExport, @Nullable String dataRegion) throws Exception
{
ViewType result = createQueryView(form, errors, forExport, dataRegion);
@@ -164,6 +167,7 @@ protected final ViewType createInitializedQueryView(Form form, BindException err
* Create the specially configured query view.
* @param dataRegion null as a convenience when only a single QueryView is being used
*/
+ @Nullable
protected abstract ViewType createQueryView(Form form, BindException errors, boolean forExport, @Nullable String dataRegion) throws Exception;
public static class QueryExportForm extends QueryForm
diff --git a/api/src/org/labkey/api/data/AJAXDetailsDisplayColumn.java b/api/src/org/labkey/api/data/AJAXDetailsDisplayColumn.java
index c750658316f..f6e52614f42 100644
--- a/api/src/org/labkey/api/data/AJAXDetailsDisplayColumn.java
+++ b/api/src/org/labkey/api/data/AJAXDetailsDisplayColumn.java
@@ -23,6 +23,7 @@
import org.labkey.api.util.ContainerContext;
import org.labkey.api.util.DOM;
import org.labkey.api.util.GUID;
+import org.labkey.api.util.HtmlString;
import org.labkey.api.util.JavaScriptFragment;
import org.labkey.api.util.StringExpression;
import org.labkey.api.view.ActionURL;
@@ -38,6 +39,7 @@
import static org.labkey.api.util.DOM.SPAN;
import static org.labkey.api.util.DOM.id;
+import static org.labkey.api.util.DOM.Attribute.style;
/**
* Uses LABKEY.Ext.CalloutTip to provide additional details, summoned via AJAX
@@ -106,7 +108,7 @@ public void renderGridCellContents(RenderContext ctx, HtmlWriter out)
props.put("target", divId);
SPAN(
- id(divId),
+ id(divId).at(style, "display:inline-flex;flex-wrap:nowrap"),
(DOM.Renderable) ret -> {
super.renderGridCellContents(ctx, out);
return ret;
diff --git a/api/src/org/labkey/api/dataiterator/SimpleTranslator.java b/api/src/org/labkey/api/dataiterator/SimpleTranslator.java
index 5dcd3249d5c..eafe66196cd 100644
--- a/api/src/org/labkey/api/dataiterator/SimpleTranslator.java
+++ b/api/src/org/labkey/api/dataiterator/SimpleTranslator.java
@@ -485,20 +485,16 @@ protected class DerivationScopedConvertColumn extends SimpleConvertColumn
final int derivationDataColInd;
final int index;
final boolean isDerivation;
- final String presentDerivationWarning;
- final String presentNonDerivationWarning;
final SimpleConvertColumn _convertCol;
- public DerivationScopedConvertColumn(int index, SimpleConvertColumn convertCol, int derivationDataColInd, boolean isDerivation, @Nullable String presentDerivationWarning, @Nullable String presentNonDerivationWarning)
+ public DerivationScopedConvertColumn(int index, SimpleConvertColumn convertCol, int derivationDataColInd, boolean isDerivation)
{
super(convertCol.fieldName, convertCol.index, convertCol.type, convertCol.defaultUnit);
_convertCol = convertCol;
this.index = index;
this.derivationDataColInd = derivationDataColInd;
this.isDerivation = isDerivation;
- this.presentDerivationWarning = presentDerivationWarning;
- this.presentNonDerivationWarning = presentNonDerivationWarning;
}
@Override
@@ -506,7 +502,7 @@ protected Object convert(Object o)
{
Object thisValue = _convertCol.convert(o);
- return getDerivationData(thisValue, derivationDataColInd, isDerivation, presentDerivationWarning, presentNonDerivationWarning);
+ return getDerivationData(thisValue, derivationDataColInd, isDerivation);
}
}
@@ -519,23 +515,18 @@ protected class DerivationScopedColumn implements Supplier
final int index;
final boolean isDerivation;
- final String presentDerivationWarning;
- final String presentNonDerivationWarning;
-
- public DerivationScopedColumn(int index, int derivationDataColInd, boolean isDerivation, @Nullable String presentDerivationWarning, @Nullable String presentNonDerivationWarning)
+ public DerivationScopedColumn(int index, int derivationDataColInd, boolean isDerivation)
{
this.index = index;
this.derivationDataColInd = derivationDataColInd;
this.isDerivation = isDerivation;
- this.presentDerivationWarning = presentDerivationWarning;
- this.presentNonDerivationWarning = presentNonDerivationWarning;
}
@Override
public Object get()
{
Object thisValue = _data.get(index);
- return getDerivationData(thisValue, derivationDataColInd, isDerivation, presentDerivationWarning, presentNonDerivationWarning);
+ return getDerivationData(thisValue, derivationDataColInd, isDerivation);
}
}
@@ -543,24 +534,14 @@ public Object get()
* @param thisValue the original field value
* @param derivationDataColInd the col index for the field used to determine if a record is child or parent
* @param isDerivationField if this field is a child only field
- * @param presentDerivationWarning the warning msg to log if a child field is present for a parent record
- * @param presentNonDerivationWarning the warning msg to log if a parent field is present for a child record
*/
- private Object getDerivationData(Object thisValue, int derivationDataColInd, boolean isDerivationField, @Nullable String presentDerivationWarning, @Nullable String presentNonDerivationWarning)
+ private Object getDerivationData(Object thisValue, int derivationDataColInd, boolean isDerivationField)
{
Object derivationData = derivationDataColInd < 0 ? null : _data.get(derivationDataColInd);
if ((isDerivationField && derivationData != null)
|| (!isDerivationField && derivationData == null))
return thisValue;
- if (thisValue != null)
- {
- if (isDerivationField && presentDerivationWarning != null)
- LOG.warn(presentDerivationWarning);
- else if (!isDerivationField && presentNonDerivationWarning != null)
- LOG.warn(presentNonDerivationWarning);
- }
-
return null;
}
diff --git a/api/webapp/WEB-INF/web.xml b/api/webapp/WEB-INF/web.xml
index 3dbc079f803..450a46349cd 100755
--- a/api/webapp/WEB-INF/web.xml
+++ b/api/webapp/WEB-INF/web.xml
@@ -58,6 +58,11 @@
*.post
+
+
+ COOKIE
+
+
/
diff --git a/audit/src/org/labkey/audit/AuditModule.java b/audit/src/org/labkey/audit/AuditModule.java
index 5be6326ee39..ac6788c32d2 100644
--- a/audit/src/org/labkey/audit/AuditModule.java
+++ b/audit/src/org/labkey/audit/AuditModule.java
@@ -19,6 +19,13 @@
import org.jetbrains.annotations.NotNull;
import org.labkey.api.audit.AuditLogService;
import org.labkey.api.audit.provider.SiteSettingsAuditProvider;
+import org.labkey.api.data.ColumnInfo;
+import org.labkey.api.data.JdbcType;
+import org.labkey.api.data.SQLFragment;
+import org.labkey.api.data.TableInfo;
+import org.labkey.api.data.WrappedColumn;
+import org.labkey.api.migration.DatabaseMigrationService;
+import org.labkey.api.migration.MigrationTableHandler;
import org.labkey.api.module.DefaultModule;
import org.labkey.api.module.ModuleContext;
import org.labkey.api.view.WebPartFactory;
@@ -27,6 +34,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
+import java.util.TreeSet;
public class AuditModule extends DefaultModule
{
@@ -89,4 +97,57 @@ public Set getProvisionedSchemaNames()
{
return Collections.singleton(AuditSchema.SCHEMA_NAME);
}
+
+ private final Set _registeredMigrationTables = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+
+ @Override
+ public void registerMigrationHandlers(@NotNull DatabaseMigrationService service)
+ {
+ service.registerSchemaContributor(AuditSchema.SCHEMA_NAME, schema ->
+ schema.getTableNames().stream()
+ .map(schema::getTable)
+ .filter(table -> table != null && _registeredMigrationTables.add(table.getSelectName()))
+ .forEach(table -> service.registerTableHandler(new MigrationTableHandler()
+ {
+ @Override
+ public TableInfo getTableInfo()
+ {
+ return table;
+ }
+
+ @Override
+ public ColumnInfo handleColumn(ColumnInfo col)
+ {
+ if ("hasdetails".equalsIgnoreCase(col.getName()))
+ return new HasDetailsCastColumn(col);
+ return col;
+ }
+ })));
+ }
+
+ // Some legacy source databases store the DatasetAuditDomain "HasDetails" column as varchar
+ // while the target was provisioned as boolean. CAST to BIT in the source SELECT and report
+ // BOOLEAN as the JdbcType so the migration's INSERT parameter binds cleanly into the
+ // target's boolean column (otherwise the parameter inherits the source column's VARCHAR
+ // type and PG rejects the bound value).
+ private static final class HasDetailsCastColumn extends WrappedColumn
+ {
+ private HasDetailsCastColumn(ColumnInfo col)
+ {
+ super(col, col.getName());
+ }
+
+ @Override
+ @NotNull
+ public JdbcType getJdbcType()
+ {
+ return JdbcType.BOOLEAN;
+ }
+
+ @Override
+ public SQLFragment getValueSql(String tableAlias)
+ {
+ return new SQLFragment("CAST(").append(super.getValueSql(tableAlias)).append(" AS BIT)");
+ }
+ }
}
diff --git a/experiment/src/org/labkey/experiment/api/SampleTypeUpdateServiceDI.java b/experiment/src/org/labkey/experiment/api/SampleTypeUpdateServiceDI.java
index 92510061fc5..13774614ac3 100644
--- a/experiment/src/org/labkey/experiment/api/SampleTypeUpdateServiceDI.java
+++ b/experiment/src/org/labkey/experiment/api/SampleTypeUpdateServiceDI.java
@@ -1607,9 +1607,6 @@ private boolean rowExists(String name)
static class _SamplesCoerceDataIterator extends SimpleTranslator
{
- private static final String INVALID_ALIQUOT_PROPERTY = "An aliquot-specific property [%1$s] value has been ignored for a non-aliquot sample.";
- private static final String INVALID_NON_ALIQUOT_PROPERTY = "A sample property [%1$s] value has been ignored for an aliquot.";
-
private final ExpSampleTypeImpl _sampleType;
private final Unit _sampleTypeBaseUnit;
@@ -1664,14 +1661,12 @@ else if (amountImportAliasSet.contains(from.getName()))
String name = to.getName();
boolean isScopedField = scopedFields.containsKey(name);
- String ignoredAliquotPropValue = String.format(INVALID_ALIQUOT_PROPERTY, name);
- String ignoredMetaPropValue = String.format(INVALID_NON_ALIQUOT_PROPERTY, name);
if (to.getPropertyType() == PropertyType.ATTACHMENT || to.getPropertyType() == PropertyType.FILE_LINK)
{
if (isScopedField)
{
ColumnInfo clone = new BaseColumnInfo(to);
- addColumn(clone, new DerivationScopedColumn(i, aliquotedFromDataColInd, scopedFields.get(name), ignoredAliquotPropValue, ignoredMetaPropValue));
+ addColumn(clone, new DerivationScopedColumn(i, aliquotedFromDataColInd, scopedFields.get(name)));
}
else
addColumn(to, i);
@@ -1683,7 +1678,7 @@ else if (to.isMultiValued() || to.getFk() instanceof MultiValuedForeignKey)
{
var col = new BaseColumnInfo(getInput().getColumnInfo(i));
col.setName(name);
- addColumn(col, new DerivationScopedColumn(i, aliquotedFromDataColInd, scopedFields.get(name), ignoredAliquotPropValue, ignoredMetaPropValue));
+ addColumn(col, new DerivationScopedColumn(i, aliquotedFromDataColInd, scopedFields.get(name)));
}
else
addColumn(to.getName(), i);
@@ -1754,7 +1749,7 @@ private void _addConvertColumn(String name, int fromIndex, JdbcType toType, @Nul
private void _addConvertColumn(ColumnInfo col, int fromIndex, int derivationDataColInd, boolean isAliquotField)
{
SimpleConvertColumn c = createConvertColumn(col, fromIndex, RemapMissingBehavior.Error);
- c = new DerivationScopedConvertColumn(fromIndex, c, derivationDataColInd, isAliquotField, String.format(INVALID_ALIQUOT_PROPERTY, col.getName()), String.format(INVALID_NON_ALIQUOT_PROPERTY, col.getName()));
+ c = new DerivationScopedConvertColumn(fromIndex, c, derivationDataColInd, isAliquotField);
addColumn(col, c);
}