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
95 changes: 95 additions & 0 deletions api/src/org/labkey/api/data/CompareType.java
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,39 @@ protected Collection getCollectionParam(Object value)
* <xsd:enumeration value="arrayisempty"/>
* <xsd:enumeration value="arrayisnotempty"/>
*/


public static final CompareType ARRAY_IS_EMPTY = new CompareType("Is Empty", "arrayisempty", "ARRAYISEMPTY", false, null, OperatorType.ARRAYISEMPTY)
{
@Override
public ArrayIsEmptyClause createFilterClause(@NotNull FieldKey fieldKey, Object value)
{
return new ArrayIsEmptyClause(fieldKey);
}

@Override
public boolean meetsCriteria(ColumnRenderProperties col, Object value, Object[] filterValues)
{
throw new UnsupportedOperationException("Conditional formatting not yet supported for Multi Choices");
}
};


public static final CompareType ARRAY_IS_NOT_EMPTY = new CompareType("Is Not Empty", "arrayisnotempty", "ARRAYISNOTEMPTY", false, null, OperatorType.ARRAYISNOTEMPTY)
{
@Override
public ArrayIsEmptyClause createFilterClause(@NotNull FieldKey fieldKey, Object value)
{
return new ArrayIsNotEmptyClause(fieldKey);
}

@Override
public boolean meetsCriteria(ColumnRenderProperties col, Object value, Object[] filterValues)
{
throw new UnsupportedOperationException("Conditional formatting not yet supported for Multi Choices");
}
};

public static final CompareType ARRAY_CONTAINS_ALL = new CompareType("Contains All", "arraycontainsall", "ARRAYCONTAINSALL", true, null, OperatorType.ARRAYCONTAINSALL)
{
@Override
Expand Down Expand Up @@ -981,6 +1014,68 @@ public Pair<SQLFragment, SQLFragment> getSqlFragments(Map<FieldKey, ? extends Co

}

private static class ArrayIsEmptyClause extends ArrayClause
{
public ArrayIsEmptyClause(@NotNull FieldKey fieldKey, CompareType comparison, boolean negated)
{
super(fieldKey, comparison, null, negated);
}

public ArrayIsEmptyClause(@NotNull FieldKey fieldKey)
{
this(fieldKey, CompareType.ARRAY_IS_EMPTY, false);
}

@Override
public SQLFragment toSQLFragment(Map<FieldKey, ? extends ColumnInfo> columnMap, SqlDialect dialect)
{
ColumnInfo colInfo = columnMap != null ? columnMap.get(_fieldKey) : null;
var alias = SimpleFilter.getAliasForColumnFilter(dialect, colInfo, _fieldKey);

SQLFragment columnFragment = new SQLFragment().appendIdentifier(alias);

SQLFragment sql = dialect.array_is_empty(columnFragment);
if (!_negated)
return sql;
return new SQLFragment(" NOT (").append(sql).append(")");
}

@Override
public String getLabKeySQLWhereClause(Map<FieldKey, ? extends ColumnInfo> columnMap)
{
return "array_is_empty(" + getLabKeySQLColName(_fieldKey) + ")";
}

@Override
public void appendFilterText(StringBuilder sb, ColumnNameFormatter formatter)
{
sb.append("is empty");
}

}

private static class ArrayIsNotEmptyClause extends ArrayIsEmptyClause
{

public ArrayIsNotEmptyClause(@NotNull FieldKey fieldKey)
{
super(fieldKey, CompareType.ARRAY_IS_NOT_EMPTY, true);
}

@Override
public String getLabKeySQLWhereClause(Map<FieldKey, ? extends ColumnInfo> columnMap)
{
return "NOT array_is_empty(" + getLabKeySQLColName(_fieldKey) + ")";
}

@Override
public void appendFilterText(StringBuilder sb, ColumnNameFormatter formatter)
{
sb.append("is not empty");
}

}

private static class ArrayContainsAllClause extends ArrayClause
{

Expand Down
2 changes: 1 addition & 1 deletion api/src/org/labkey/api/data/SimpleFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ public static abstract class MultiValuedFilterClause extends CompareType.Abstrac
public MultiValuedFilterClause(@NotNull FieldKey fieldKey, CompareType comparison, Collection<?> params, boolean negated)
{
super(fieldKey);
params = new ArrayList<>(params); // possibly immutable
params = params == null ? new ArrayList<>() : new ArrayList<>(params); // possibly immutable
if (params.contains(null)) //params.size() == 0 ||
{
_includeNull = true;
Expand Down
17 changes: 17 additions & 0 deletions api/src/org/labkey/api/data/TableChange.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.labkey.api.data.PropertyStorageSpec.Index;
import org.labkey.api.data.TableInfo.IndexDefinition;
import org.labkey.api.exp.PropertyDescriptor;
import org.labkey.api.exp.PropertyType;
import org.labkey.api.exp.property.Domain;
import org.labkey.api.exp.property.DomainKind;
import org.labkey.api.util.logging.LogHelper;
Expand Down Expand Up @@ -58,6 +59,7 @@ public class TableChange
private Collection<Constraint> _constraints;
private Set<String> _indicesToBeDroppedByName;
private IndexSizeMode _sizeMode = IndexSizeMode.Auto;
private Map<String, PropertyType> _oldPropTypes;

/** In most cases, domain knows the storage table name **/
public TableChange(Domain domain, ChangeType changeType)
Expand Down Expand Up @@ -329,6 +331,16 @@ public void setForeignKeys(Collection<PropertyStorageSpec.ForeignKey> foreignKey
_foreignKeys = foreignKeys;
}

public Map<String, PropertyType> getOldPropTypes()
{
return _oldPropTypes;
}

public void setOldPropTypes(Map<String, PropertyType> oldPropTypes)
{
_oldPropTypes = oldPropTypes;
}

public final List<PropertyStorageSpec> toSpecs(Collection<String> columnNames)
{
final Domain domain = _domain;
Expand All @@ -349,6 +361,11 @@ public final List<PropertyStorageSpec> toSpecs(Collection<String> columnNames)
.collect(Collectors.toList());
}

public void setOldPropertyTypes(Map<String, PropertyType> oldPropTypes)
{
_oldPropTypes = oldPropTypes;
}
Comment on lines +364 to +367
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Duplicate method definition. The method setOldPropertyTypes is defined twice in this class - once at lines 339-342 as setOldPropTypes and again at lines 364-367 as setOldPropertyTypes. Remove one of these duplicate methods.

Copilot uses AI. Check for mistakes.

public enum ChangeType
{
CreateTable,
Expand Down
6 changes: 6 additions & 0 deletions api/src/org/labkey/api/data/dialect/SqlDialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,12 @@ public SQLFragment array_construct(SQLFragment[] elements)
throw new UnsupportedOperationException(getClass().getSimpleName() + " does not implement");
}

public SQLFragment array_is_empty(SQLFragment a)
{
assert !supportsArrays();
throw new UnsupportedOperationException(getClass().getSimpleName() + " does not implement");
}

// element a is in array b
public SQLFragment element_in_array(SQLFragment a, SQLFragment b)
{
Expand Down
6 changes: 3 additions & 3 deletions api/src/org/labkey/api/query/AbstractQueryChangeListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ public void queryCreated(User user, Container container, ContainerFilter scope,
protected abstract void queryCreated(User user, Container container, ContainerFilter scope, SchemaKey schema, String query);

@Override
public void queryChanged(User user, Container container, ContainerFilter scope, SchemaKey schema, @NotNull QueryProperty property, @NotNull Collection<QueryPropertyChange<?>> changes)
public void queryChanged(User user, Container container, ContainerFilter scope, SchemaKey schema, String queryName, @NotNull QueryProperty property, @NotNull Collection<QueryPropertyChange<?>> changes)
{
for (QueryPropertyChange<?> change : changes)
queryChanged(user, container, scope, schema, change);
queryChanged(user, container, scope, schema, queryName, change);
}

protected abstract void queryChanged(User user, Container container, ContainerFilter scope, SchemaKey schema, QueryPropertyChange<?> change);
protected abstract void queryChanged(User user, Container container, ContainerFilter scope, SchemaKey schema, String queryName, QueryPropertyChange<?> change);

@Override
public void queryDeleted(User user, Container container, ContainerFilter scope, SchemaKey schema, @NotNull Collection<String> queries)
Expand Down
Loading