support default project name and column name for cross() (#2518)
This commit is contained in:
parent
f478356e17
commit
e89eaf0ee2
@ -3,6 +3,7 @@ package com.google.refine;
|
||||
import com.google.refine.expr.ExpressionUtils;
|
||||
import com.google.refine.expr.HasFieldsListImpl;
|
||||
import com.google.refine.expr.WrappedRow;
|
||||
import com.google.refine.expr.functions.Cross;
|
||||
import com.google.refine.model.Column;
|
||||
import com.google.refine.model.Project;
|
||||
import com.google.refine.model.Row;
|
||||
@ -76,6 +77,14 @@ public class LookupCacheManager {
|
||||
return;
|
||||
}
|
||||
|
||||
// if this is a lookup on the index column
|
||||
if (lookup.targetColumnName.equals(Cross.INDEX_COLUMN_NAME)) {
|
||||
for (int r = 0; r < targetProject.rows.size(); r++) {
|
||||
lookup.valueToRowIndices.put(String.valueOf(r) , Collections.singletonList(r));
|
||||
}
|
||||
return; // return directly
|
||||
}
|
||||
|
||||
Column targetColumn = targetProject.columnModel.getColumnByName(lookup.targetColumnName);
|
||||
if (targetColumn == null) {
|
||||
throw new LookupException("Unable to find column " + lookup.targetColumnName + " in project " + targetProjectMetadata.getName());
|
||||
|
@ -41,24 +41,37 @@ import com.google.refine.expr.EvalError;
|
||||
import com.google.refine.expr.WrappedCell;
|
||||
import com.google.refine.grel.ControlFunctionRegistry;
|
||||
import com.google.refine.grel.Function;
|
||||
import com.google.refine.model.Project;
|
||||
import com.google.refine.util.GetProjectIDException;
|
||||
import com.google.refine.util.LookupException;
|
||||
|
||||
public class Cross implements Function {
|
||||
|
||||
public static final String INDEX_COLUMN_NAME = "_OpenRefine_Index_Column_Name_";
|
||||
|
||||
@Override
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length == 3) {
|
||||
if (1 <= args.length && args.length <= 3) {
|
||||
// 1st argument can take either value or cell(for backward compatibility)
|
||||
Object v = args[0];
|
||||
Object targetProjectName = args[1];
|
||||
Object targetColumnName = args[2];
|
||||
// if 2nd argument is omitted or set to "", use the current project name
|
||||
Object targetProjectName = "";
|
||||
boolean isCurrentProject = false;
|
||||
if (args.length < 2 || args[1].equals("")) {
|
||||
isCurrentProject = true;
|
||||
} else {
|
||||
targetProjectName = args[1];
|
||||
}
|
||||
// if 3rd argument is omitted or set to "", use the index column
|
||||
Object targetColumnName = args.length < 3 || args[2].equals("") ? INDEX_COLUMN_NAME: args[2];
|
||||
|
||||
long targetProjectID;
|
||||
ProjectLookup lookup;
|
||||
|
||||
if (v != null && targetProjectName instanceof String && targetColumnName instanceof String) {
|
||||
try {
|
||||
targetProjectID = ProjectManager.singleton.getProjectID((String) targetProjectName);
|
||||
targetProjectID = isCurrentProject ? ((Project) bindings.get("project")).id :
|
||||
ProjectManager.singleton.getProjectID((String) targetProjectName);
|
||||
} catch (GetProjectIDException e) {
|
||||
return new EvalError(e.getMessage());
|
||||
}
|
||||
@ -76,17 +89,21 @@ public class Cross implements Function {
|
||||
}
|
||||
}
|
||||
}
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects a cell or value, a project name to look up, and a column name in that project");
|
||||
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects a cell or value, a project name to look up (optional), and a column name in that project (optional)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Looks up the given value in the target column of the target project, returns an array of matched rows, cell will be interpreted as cell.value. Two values match if and only if they have the same string representation";
|
||||
return "Looks up the given value in the target column of the target project, returns an array of matched rows. Two values match if and only if they have the same string representation. " +
|
||||
"The first argument will be interpreted as cell.value if set to cell. " +
|
||||
"The second argument will be interpreted as the current project name if omitted or set to \"\". " +
|
||||
"The third argument will be interpreted as the index (starts from 0) column if omitted or set to \"\"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParams() {
|
||||
return "cell or value, string projectName, string columnName";
|
||||
return "cell or value, string projectName (optional), string columnName (optional)";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,6 +163,49 @@ public class CrossTests extends RefineTest {
|
||||
Assert.assertEquals(address, "50 Broadway Ave.");
|
||||
}
|
||||
|
||||
@Test
|
||||
// lookup the row with index 0 in the current project
|
||||
public void crossFunctionOneArgumentTest() throws Exception {
|
||||
Row row = (((WrappedRow) ((HasFieldsListImpl) invoke("cross", 0)).get(0)).row);
|
||||
String address = row.getCell(1).value.toString();
|
||||
Assert.assertEquals(address, "mary");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void crossFunctionOneArgumentTest1() throws Exception {
|
||||
Row row = (((WrappedRow) ((HasFieldsListImpl) invoke("cross", 0, "")).get(0)).row);
|
||||
String address = row.getCell(1).value.toString();
|
||||
Assert.assertEquals(address, "mary");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void crossFunctionOneArgumentTest2() throws Exception {
|
||||
Row row = (((WrappedRow) ((HasFieldsListImpl) invoke("cross", 1, "", "")).get(0)).row);
|
||||
String address = row.getCell(1).value.toString();
|
||||
Assert.assertEquals(address, "john");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void crossFunctionTwoArgumentTest() throws Exception {
|
||||
Row row = (((WrappedRow) ((HasFieldsListImpl) invoke("cross", "lamp", "", "gift")).get(0)).row);
|
||||
String address = row.getCell(1).value.toString();
|
||||
Assert.assertEquals(address, "mary");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void crossFunctionTwoArgumentTest1() throws Exception {
|
||||
Row row = (((WrappedRow) ((HasFieldsListImpl) invoke("cross", 0, "My Address Book")).get(0)).row);
|
||||
String address = row.getCell(1).value.toString();
|
||||
Assert.assertEquals(address, "120 Main St.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void crossFunctionTwoArgumentTest2() throws Exception {
|
||||
Row row = (((WrappedRow) ((HasFieldsListImpl) invoke("cross", 0, "My Address Book", "")).get(0)).row);
|
||||
String address = row.getCell(1).value.toString();
|
||||
Assert.assertEquals(address, "120 Main St.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void crossFunctionOneToOneTest() throws Exception {
|
||||
Row row = (((WrappedRow) ((HasFieldsListImpl) invoke("cross", "mary", "My Address Book", "friend")).get(0)).row);
|
||||
@ -328,7 +371,7 @@ public class CrossTests extends RefineTest {
|
||||
@Test
|
||||
public void crossFunctionNonLiteralValue() throws Exception {
|
||||
Assert.assertEquals(((EvalError) invoke("cross", null, "My Address Book", "friend")).message,
|
||||
"cross expects a cell or value, a project name to look up, and a column name in that project");
|
||||
"cross expects a cell or value, a project name to look up (optional), and a column name in that project (optional)");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -346,10 +389,14 @@ public class CrossTests extends RefineTest {
|
||||
return function.call(bindings,args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void serializeCross() {
|
||||
String json = "{\"description\":\"Looks up the given value in the target column of the target project, returns an array of matched rows, cell will be interpreted as cell.value. Two values match if and only if they have the same string representation\",\"params\":\"cell or value, string projectName, string columnName\",\"returns\":\"array\"}";
|
||||
String json = "{\"description\":\"Looks up the given value in the target column of the target project, returns an array of matched rows. Two values match if and only if they have the same string representation. " +
|
||||
"The first argument will be interpreted as cell.value if set to cell. " +
|
||||
"The second argument will be interpreted as the current project name if omitted or set to \\\"\\\". " +
|
||||
"The third argument will be interpreted as the index (starts from 0) column if omitted or set to \\\"\\\"\"," +
|
||||
"\"params\":\"cell or value, string projectName (optional), string columnName (optional)\",\"returns\":\"array\"}";
|
||||
TestUtils.isSerializedTo(new Cross(), json);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user