Fixed SQL Select statement generation. The method that
generates the statements in the Relation class now takes two additional parameters and is more flexible.
This commit is contained in:
parent
02fb01a55e
commit
3ce3e7f54a
2 changed files with 60 additions and 74 deletions
|
@ -240,7 +240,7 @@ public final class NodeManager {
|
||||||
if (node.isNullNode ()) {
|
if (node.isNullNode ()) {
|
||||||
if (node.created() < rel.otherType.getLastDataChange ())
|
if (node.created() < rel.otherType.getLastDataChange ())
|
||||||
node = null; // cached null not valid anymore
|
node = null; // cached null not valid anymore
|
||||||
// } else if (app.doesSubnodeChecking () && home.contains (node) < 0) {
|
// } else if (false && app.doesSubnodeChecking () && home.contains (node) < 0) {
|
||||||
} else if (!rel.checkConstraints (home, node)) {
|
} else if (!rel.checkConstraints (home, node)) {
|
||||||
node = null;
|
node = null;
|
||||||
}
|
}
|
||||||
|
@ -606,7 +606,7 @@ public final class NodeManager {
|
||||||
q = "SELECT "+idfield+" FROM "+table+" "+home.getSubnodeRelation();
|
q = "SELECT "+idfield+" FROM "+table+" "+home.getSubnodeRelation();
|
||||||
} else {
|
} else {
|
||||||
// let relation object build the query
|
// let relation object build the query
|
||||||
q = "SELECT "+idfield+" FROM "+table + rel.buildQuery (home, home.getNonVirtualParent (), null);
|
q = "SELECT "+idfield+" FROM "+table + rel.buildQuery (home, home.getNonVirtualParent (), null, " WHERE ", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logSql)
|
if (logSql)
|
||||||
|
@ -668,9 +668,19 @@ public final class NodeManager {
|
||||||
TableDataSet tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
TableDataSet tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
||||||
try {
|
try {
|
||||||
|
|
||||||
tds.where (rel.buildWhere (home, home.getNonVirtualParent (), null));
|
String q = null;
|
||||||
if (rel.order != null)
|
if (home.getSubnodeRelation() != null) {
|
||||||
tds.order (rel.order);
|
// HACK: cut away the "where" part of manually set subnoderelation
|
||||||
|
q = home.getSubnodeRelation().trim().substring(5);
|
||||||
|
} else {
|
||||||
|
// let relation object build the query
|
||||||
|
q = rel.buildQuery (home, home.getNonVirtualParent (), null, "", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
tds.where (q);
|
||||||
|
|
||||||
|
if (rel.getOrder () != null)
|
||||||
|
tds.order (rel.getOrder ());
|
||||||
|
|
||||||
if (logSql)
|
if (logSql)
|
||||||
app.logEvent ("### getNodes: "+tds.getSelectString());
|
app.logEvent ("### getNodes: "+tds.getSelectString());
|
||||||
|
@ -717,12 +727,20 @@ public final class NodeManager {
|
||||||
|
|
||||||
QueryDataSet qds = null;
|
QueryDataSet qds = null;
|
||||||
try {
|
try {
|
||||||
String qstr = "SELECT count(*) FROM "+table+rel.buildQuery (home, home.getNonVirtualParent (), null);
|
|
||||||
|
String q = null;
|
||||||
|
if (home.getSubnodeRelation() != null) {
|
||||||
|
// use the manually set subnoderelation of the home node
|
||||||
|
q = "SELECT count(*) FROM "+table+" "+home.getSubnodeRelation();
|
||||||
|
} else {
|
||||||
|
// let relation object build the query
|
||||||
|
q = "SELECT count(*) FROM "+table + rel.buildQuery (home, home.getNonVirtualParent (), null, " WHERE ", false);
|
||||||
|
}
|
||||||
|
|
||||||
if (logSql)
|
if (logSql)
|
||||||
app.logEvent ("### countNodes: "+qstr);
|
app.logEvent ("### countNodes: "+q);
|
||||||
|
|
||||||
qds = new QueryDataSet (con, qstr);
|
qds = new QueryDataSet (con, q);
|
||||||
|
|
||||||
qds.fetchRecords ();
|
qds.fetchRecords ();
|
||||||
if (qds.size () == 0)
|
if (qds.size () == 0)
|
||||||
|
@ -860,12 +878,11 @@ public final class NodeManager {
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
System.err.println ("GETNODEBYRELATION "+rel);
|
|
||||||
TableDataSet tds = null;
|
TableDataSet tds = null;
|
||||||
try {
|
try {
|
||||||
DbMapping dbm = rel.otherType;
|
DbMapping dbm = rel.otherType;
|
||||||
tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
||||||
String where = rel.buildWhere (home, home.getNonVirtualParent (), kstr);
|
String where = rel.buildQuery (home, home.getNonVirtualParent (), kstr, "", false);
|
||||||
|
|
||||||
tds.where (where);
|
tds.where (where);
|
||||||
|
|
||||||
|
@ -900,7 +917,7 @@ public final class NodeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// a utility method to escape single quotes
|
// a utility method to escape single quotes
|
||||||
private String escape (String str) {
|
/* private String escape (String str) {
|
||||||
if (str == null)
|
if (str == null)
|
||||||
return null;
|
return null;
|
||||||
if (str.indexOf ("'") < 0)
|
if (str.indexOf ("'") < 0)
|
||||||
|
@ -914,7 +931,7 @@ public final class NodeManager {
|
||||||
sbuf.append (c);
|
sbuf.append (c);
|
||||||
}
|
}
|
||||||
return sbuf.toString ();
|
return sbuf.toString ();
|
||||||
}
|
} */
|
||||||
|
|
||||||
|
|
||||||
public Object[] getCacheEntries () {
|
public Object[] getCacheEntries () {
|
||||||
|
|
|
@ -56,7 +56,6 @@ public class Relation {
|
||||||
public String order;
|
public String order;
|
||||||
public String groupbyorder;
|
public String groupbyorder;
|
||||||
public String groupby;
|
public String groupby;
|
||||||
public String dogroupby;
|
|
||||||
public String prototype;
|
public String prototype;
|
||||||
public String groupbyprototype;
|
public String groupbyprototype;
|
||||||
public String filter;
|
public String filter;
|
||||||
|
@ -303,15 +302,9 @@ public class Relation {
|
||||||
return accessor == null || accessor.equals (otherType.getIDField ());
|
return accessor == null || accessor.equals (otherType.getIDField ());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
/*
|
|
||||||
if (otherType == null)
|
|
||||||
return false;
|
|
||||||
if (remoteField == null)
|
|
||||||
// if remote field is null, it is assumed that it points to the primary key
|
|
||||||
return true;
|
|
||||||
return remoteField.equalsIgnoreCase (otherType.getIDField()); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Relation getSubnodeRelation () {
|
public Relation getSubnodeRelation () {
|
||||||
// return subnoderelation;
|
// return subnoderelation;
|
||||||
return null;
|
return null;
|
||||||
|
@ -326,31 +319,6 @@ public class Relation {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the local column name for this relation to use in where clauses of select statements.
|
|
||||||
* This uses the home node's id as fallback if local field is not specified.
|
|
||||||
*/
|
|
||||||
/* public String[] getLocalFields () {
|
|
||||||
if (constraints == null)
|
|
||||||
return new String[0];
|
|
||||||
String[] retval = new String[constraints.length];
|
|
||||||
for (int i=0; i<constraints.length; i++)
|
|
||||||
retval[i] = constraints[i].localName;
|
|
||||||
return retval;
|
|
||||||
} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the "remote" column name for this relation. Uses the remote node's id as fallback if the remote field is not specified.
|
|
||||||
*/
|
|
||||||
/* public String[] getRemoteFields () {
|
|
||||||
if (constraints == null)
|
|
||||||
return new String[0];
|
|
||||||
String[] retval = new String[constraints.length];
|
|
||||||
for (int i=0; i<constraints.length; i++)
|
|
||||||
retval[i] = constraints[i].foreignName;
|
|
||||||
return retval;
|
|
||||||
} */
|
|
||||||
|
|
||||||
public DbMapping getVirtualMapping () {
|
public DbMapping getVirtualMapping () {
|
||||||
if (!virtual)
|
if (!virtual)
|
||||||
return null;
|
return null;
|
||||||
|
@ -427,34 +395,14 @@ public class Relation {
|
||||||
return vr;
|
return vr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String buildWhere (INode home, INode nonvirtual, String kstr) {
|
|
||||||
StringBuffer q = new StringBuffer ();
|
|
||||||
String prefix = "";
|
|
||||||
if (kstr != null) {
|
|
||||||
String accessColumn = accessor == null ? otherType.getIDField () : accessor;
|
|
||||||
q.append (accessColumn);
|
|
||||||
q.append (" = '");
|
|
||||||
q.append (escape (kstr));
|
|
||||||
q.append ("'");
|
|
||||||
prefix = " AND ";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<constraints.length; i++) {
|
|
||||||
q.append (prefix);
|
|
||||||
constraints[i].addToQuery (q, home, nonvirtual);
|
|
||||||
prefix = " AND ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter != null) {
|
|
||||||
q.append (prefix);
|
|
||||||
q.append (filter);
|
|
||||||
}
|
|
||||||
return q.toString ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String buildQuery (INode home, INode nonvirtual, String kstr) {
|
/**
|
||||||
|
* Build the second half of an SQL select statement according to this relation
|
||||||
|
* and a local object.
|
||||||
|
*/
|
||||||
|
public String buildQuery (INode home, INode nonvirtual, String kstr, String pre, boolean useOrder) {
|
||||||
StringBuffer q = new StringBuffer ();
|
StringBuffer q = new StringBuffer ();
|
||||||
String prefix = " WHERE ";
|
String prefix = pre;
|
||||||
if (kstr != null) {
|
if (kstr != null) {
|
||||||
q.append (prefix);
|
q.append (prefix);
|
||||||
String accessColumn = accessor == null ? otherType.getIDField () : accessor;
|
String accessColumn = accessor == null ? otherType.getIDField () : accessor;
|
||||||
|
@ -474,19 +422,32 @@ public class Relation {
|
||||||
q.append (prefix);
|
q.append (prefix);
|
||||||
q.append (filter);
|
q.append (filter);
|
||||||
}
|
}
|
||||||
if (groupby != null)
|
if (groupby != null) {
|
||||||
q.append (" GROUP BY "+groupby);
|
q.append (" GROUP BY "+groupby);
|
||||||
if (order != null)
|
if (useOrder && groupbyorder != null)
|
||||||
|
q.append (" ORDER BY "+groupbyorder);
|
||||||
|
} else if (useOrder && order != null)
|
||||||
q.append (" ORDER BY "+order);
|
q.append (" ORDER BY "+order);
|
||||||
return q.toString ();
|
return q.toString ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the order section to use for this relation
|
||||||
|
*/
|
||||||
|
public String getOrder () {
|
||||||
|
if (groupby != null)
|
||||||
|
return groupbyorder;
|
||||||
|
else
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the child node fullfills the constraints defined by this relation.
|
* Check if the child node fullfills the constraints defined by this relation.
|
||||||
*/
|
*/
|
||||||
public boolean checkConstraints (Node parent, Node child) {
|
public boolean checkConstraints (Node parent, Node child) {
|
||||||
for (int i=0; i<constraints.length; i++) {
|
for (int i=0; i<constraints.length; i++) {
|
||||||
String propname = otherType.columnNameToProperty (constraints[i].foreignName);
|
String propname = constraints[i].foreignProperty ();
|
||||||
if (propname != null) {
|
if (propname != null) {
|
||||||
INode home = constraints[i].isGroupby ? parent : parent.getNonVirtualParent ();
|
INode home = constraints[i].isGroupby ? parent : parent.getNonVirtualParent ();
|
||||||
String localName = constraints[i].localName;
|
String localName = constraints[i].localName;
|
||||||
|
@ -595,6 +556,14 @@ public class Relation {
|
||||||
return foreignName == null || foreignName.equals (otherType.getIDField ());
|
return foreignName == null || foreignName.equals (otherType.getIDField ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String foreignProperty () {
|
||||||
|
return otherType.columnNameToProperty (foreignName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String localProperty () {
|
||||||
|
return ownType.columnNameToProperty (localName);
|
||||||
|
}
|
||||||
|
|
||||||
public String toString () {
|
public String toString () {
|
||||||
return ownType+"."+localName+"="+tableName+"."+foreignName;
|
return ownType+"."+localName+"="+tableName+"."+foreignName;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue