Skip to content

Commit 7af0e28

Browse files
committed
Fixed bug mapping fields to models in the new getSelectStatement() method in the ServiceRequest class
1 parent 7479ca6 commit 7af0e28

File tree

1 file changed

+144
-61
lines changed

1 file changed

+144
-61
lines changed

src/javaxt/express/ServiceRequest.java

Lines changed: 144 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,9 +1340,10 @@ public JSONArray toJson(){
13401340
//**************************************************************************
13411341
/** Returns a SQL "select" statement for the current request. Compiles the
13421342
* select statement using an array of Fields returned by the getFields()
1343-
* method. If no fields are found in the request, a "select *" statement is
1344-
* returned. Otherwise, a select statement is returned, starting with
1345-
* "select " for convenience.
1343+
* method. Prepends a table name to each field, if given. If no fields are
1344+
* found in the request, a "select *" statement is returned. Otherwise, a
1345+
* select statement is returned, starting with "select ".
1346+
*
13461347
* @param tableName If given, fields that are not functions are prepended
13471348
* with a table name. This parameter is optional.
13481349
*/
@@ -1379,88 +1380,170 @@ public String getSelectStatement(String tableName){
13791380
//**************************************************************************
13801381
/** Returns a SQL "select" statement for the current request. Compiles the
13811382
* "select" statement using using an array of Fields returned by the
1382-
* getFields() method. If no fields are found in the request, a
1383-
* "select *" statement is returned. Otherwise, a select statement is
1384-
* returned, starting with "select " for convenience.
1383+
* getFields() method. Prepends a table name to each field by mapping
1384+
* fields to models.
13851385
*
1386-
* @param c Model classes used to identify fields. If a field is matched to
1387-
* a model the field name (column name) is prepended with a table name.
1388-
* This parameter is optional.
1386+
* @param model One or more Model classes used to identify fields. If a
1387+
* field is matched to a model the field name (column name) is prepended
1388+
* with a table name. Order is important.
13891389
*/
1390-
public String getSelectStatement(Class... c){
1391-
ArrayList<HashMap<String, Object>> arr = new ArrayList<>();
1392-
try{
1393-
for (Class cls : c){
1394-
if (Model.class.isAssignableFrom(cls)){
1395-
try{
1396-
arr.add(WebService.getTableAndFields(cls));
1390+
public String getSelectStatement(Class... model){
1391+
1392+
//Get fields
1393+
Field[] fields = getFields();
1394+
if (fields==null) fields = new Field[0];
1395+
1396+
1397+
//Get models
1398+
ArrayList<Class> models = new ArrayList<>();
1399+
for (Class cls : model){
1400+
if (Model.class.isAssignableFrom(cls)){
1401+
models.add(cls);
1402+
}
1403+
else{
1404+
throw new IllegalArgumentException(
1405+
cls.getSimpleName() + " is not a javaxt.sql.Model");
1406+
}
1407+
}
1408+
1409+
1410+
//If there are no models, call the other getSelectStatement() method
1411+
if (models.isEmpty()){
1412+
HashMap<String, Object> tablesAndFields = null;
1413+
return "select " + getSelectStatement(tablesAndFields);
1414+
}
1415+
1416+
1417+
//Compile "select" statement
1418+
String[] select = new String[fields.length];
1419+
ArrayList<String> unmatchedTables = new ArrayList<>();
1420+
for (Class cls : models){
1421+
try{
1422+
int numMatches = 0;
1423+
HashMap<String, Object> tablesAndFields = WebService.getTableAndFields(cls);
1424+
String[] selectStatements = getSelectStatements(fields, tablesAndFields);
1425+
for (int i=0; i<selectStatements.length; i++){
1426+
String selectStatement = selectStatements[i];
1427+
if (selectStatement==null) continue;
1428+
if (select[i]==null){
1429+
select[i] = selectStatement;
1430+
numMatches++;
13971431
}
1398-
catch(Exception e){}
13991432
}
1433+
1434+
if (numMatches==0){
1435+
String tableName = (String) tablesAndFields.get("tableName");
1436+
unmatchedTables.add(tableName);
1437+
}
1438+
14001439
}
1440+
catch(Exception e){}
1441+
}
1442+
1443+
1444+
1445+
StringBuilder sql = new StringBuilder();
1446+
for (String s : select){
1447+
if (s==null) continue;
1448+
if (sql.length()>0) sql.append(", ");
1449+
sql.append(s);
1450+
}
1451+
1452+
1453+
if (sql.length()==0){
1454+
if (models.size()>1){
1455+
for (String tableName : unmatchedTables){
1456+
if (sql.length()>0) sql.append(", ");
1457+
sql.append(tableName + ".*");
1458+
}
1459+
return "select " + sql.toString();
1460+
}
1461+
else{
1462+
return "select *";
1463+
}
1464+
}
1465+
else{
1466+
return "select " + sql.toString();
14011467
}
1402-
catch(Exception e){}
1403-
return "select " + getSelectStatement(arr);
14041468
}
14051469

14061470

1471+
//**************************************************************************
1472+
//** getSelectStatement
1473+
//**************************************************************************
14071474
protected String getSelectStatement(HashMap<String, Object> tablesAndFields){
1408-
ArrayList<HashMap<String, Object>> arr = new ArrayList<>();
1409-
arr.add(tablesAndFields);
1410-
return getSelectStatement(arr);
1475+
StringBuilder sql = new StringBuilder();
1476+
for (String select : getSelectStatements(getFields(), tablesAndFields)){
1477+
if (select==null) continue;
1478+
if (sql.length()>0) sql.append(", ");
1479+
sql.append(select);
1480+
}
1481+
if (sql.length()==0) return "*";
1482+
else return sql.toString();
14111483
}
14121484

14131485

1414-
private String getSelectStatement(ArrayList<HashMap<String, Object>> tablesAndFields){
1415-
StringBuilder sql = new StringBuilder();
1416-
Field[] fields = getFields();
1417-
if (fields!=null){
1418-
for (int i=0; i<fields.length; i++){
1419-
if (i>0) sql.append(", ");
1420-
Field field = fields[i];
1486+
//**************************************************************************
1487+
//** getSelectStatements
1488+
//**************************************************************************
1489+
/** Used to match fields to columns in the database. Returns an array with
1490+
* the exact same size as the given fields array. Note that entries in the
1491+
* array may contain null values, indicating that the field was not mapped.
1492+
*/
1493+
private String[] getSelectStatements(Field[] fields, HashMap<String, Object> tablesAndFields){
1494+
if (fields==null || fields.length==0) return new String[0];
14211495

1422-
if (field.isFunction()){
1423-
sql.append(field.toString());
1424-
}
1425-
else{
1496+
String[] select = new String[fields.length];
1497+
for (int i=0; i<fields.length; i++){
1498+
Field field = fields[i];
14261499

1500+
if (field.isFunction()){
1501+
select[i] = field.toString();
1502+
}
1503+
else{
14271504

1428-
//Find table that corresponds to the field
1429-
String tableName = null;
1430-
if (tablesAndFields!=null){
1431-
String col = field.getColumn();
1432-
for (HashMap<String, Object> map : tablesAndFields){
1433-
HashMap<String, String> fieldMap = (HashMap<String, String>) map.get("fieldMap");
1434-
Iterator<String> it = fieldMap.keySet().iterator();
1435-
while (it.hasNext()){
1436-
String fieldName = it.next();
1437-
String columnName = fieldMap.get(fieldName);
1438-
if (col.equalsIgnoreCase(fieldName) || col.equalsIgnoreCase(columnName)){
1439-
tableName = (String) map.get("tableName");
1440-
break;
1441-
}
1442-
}
1443-
if (tableName!=null) break;
1505+
1506+
//Find table that corresponds to the field
1507+
String tableName = null;
1508+
if (tablesAndFields!=null){
1509+
String col = field.getColumn();
1510+
1511+
HashMap<String, String> fieldMap = (HashMap<String, String>) tablesAndFields.get("fieldMap");
1512+
Iterator<String> it = fieldMap.keySet().iterator();
1513+
while (it.hasNext()){
1514+
String fieldName = it.next();
1515+
String columnName = fieldMap.get(fieldName);
1516+
if (col.equalsIgnoreCase(fieldName) || col.equalsIgnoreCase(columnName)){
1517+
tableName = (String) tablesAndFields.get("tableName");
1518+
break;
14441519
}
14451520
}
14461521

14471522

14481523

1449-
//Add field, along with the table name and alias
1450-
if (tableName!=null && !tableName.isEmpty()){
1451-
sql.append(tableName + ".");
1452-
}
1453-
sql.append(StringUtils.camelCaseToUnderScore(field.getColumn()));
1454-
String alias = field.getAlias();
1455-
if (alias!=null && !alias.isBlank()){
1456-
sql.append(" as ");
1457-
sql.append(alias.trim());
1458-
}
1524+
//If tablesAndFields are given, yet we can't find a table for
1525+
//the field, and field is not a function, is it a valid field?
1526+
if (tableName==null) continue;
1527+
}
1528+
1529+
1530+
1531+
//Add field, along with the table name and alias
1532+
StringBuilder sql = new StringBuilder();
1533+
if (tableName!=null && !tableName.isEmpty()){
1534+
sql.append(tableName + ".");
1535+
}
1536+
sql.append(StringUtils.camelCaseToUnderScore(field.getColumn()));
1537+
String alias = field.getAlias();
1538+
if (alias!=null && !alias.isBlank()){
1539+
sql.append(" as ");
1540+
sql.append(alias.trim());
14591541
}
1542+
select[i] = sql.toString();
14601543
}
14611544
}
1462-
if (sql.length()==0) sql.append("*");
1463-
return sql.toString();
1545+
1546+
return select;
14641547
}
14651548

14661549

0 commit comments

Comments
 (0)