Implement aggressive object reference loading for Oracle pre-9.
See http://helma.org/bugs/show_bug.cgi?id=300
This commit is contained in:
parent
bb9152d2d1
commit
d170d73565
4 changed files with 77 additions and 8 deletions
|
@ -921,6 +921,7 @@ public final class DbMapping implements Updatable {
|
||||||
// assign to local variable first so we are thread safe
|
// assign to local variable first so we are thread safe
|
||||||
// (selectString may be reset by other threads)
|
// (selectString may be reset by other threads)
|
||||||
String sel = selectString;
|
String sel = selectString;
|
||||||
|
boolean isOracle = isOracle();
|
||||||
|
|
||||||
if (rel == null && sel != null) {
|
if (rel == null && sel != null) {
|
||||||
return new StringBuffer(sel);
|
return new StringBuffer(sel);
|
||||||
|
@ -962,13 +963,24 @@ public final class DbMapping implements Updatable {
|
||||||
if (!joins[i].otherType.isRelational()) {
|
if (!joins[i].otherType.isRelational()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (isOracle) {
|
||||||
|
// generate an old-style oracle left join - see
|
||||||
|
// http://www.praetoriate.com/oracle_tips_outer_joins.htm
|
||||||
|
s.append(", ");
|
||||||
|
s.append(joins[i].otherType.getTableName());
|
||||||
|
s.append(" ");
|
||||||
|
s.append(Relation.JOIN_PREFIX);
|
||||||
|
s.append(joins[i].propName);
|
||||||
|
s.append(" ");
|
||||||
|
} else {
|
||||||
s.append("LEFT OUTER JOIN ");
|
s.append("LEFT OUTER JOIN ");
|
||||||
s.append(joins[i].otherType.getTableName());
|
s.append(joins[i].otherType.getTableName());
|
||||||
s.append(" AS ");
|
s.append(" ");
|
||||||
s.append(Relation.JOIN_PREFIX);
|
s.append(Relation.JOIN_PREFIX);
|
||||||
s.append(joins[i].propName);
|
s.append(joins[i].propName);
|
||||||
s.append(" ON ");
|
s.append(" ON ");
|
||||||
joins[i].renderJoinConstraints(s);
|
joins[i].renderJoinConstraints(s, isOracle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache rendered string for later calls, but only if it wasn't
|
// cache rendered string for later calls, but only if it wasn't
|
||||||
|
@ -1064,6 +1076,37 @@ public final class DbMapping implements Updatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add constraints to select query string to join object references
|
||||||
|
*/
|
||||||
|
public void addJoinConstraints(StringBuffer s, String pre) {
|
||||||
|
boolean isOracle = isOracle();
|
||||||
|
String prefix = pre;
|
||||||
|
|
||||||
|
if (!isOracle) {
|
||||||
|
// constraints have already been rendered by getSelect()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < joins.length; i++) {
|
||||||
|
if (!joins[i].otherType.isRelational()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
s.append(prefix);
|
||||||
|
joins[i].renderJoinConstraints(s, isOracle);
|
||||||
|
prefix = " AND ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the database behind this an Oracle db?
|
||||||
|
*
|
||||||
|
* @return true if the dbsource is using an oracle JDBC driver
|
||||||
|
*/
|
||||||
|
public boolean isOracle() {
|
||||||
|
return dbSource != null && dbSource.isOracle();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class DbSource {
|
||||||
private String driver;
|
private String driver;
|
||||||
protected String user;
|
protected String user;
|
||||||
private String password;
|
private String password;
|
||||||
|
private boolean isOracle;
|
||||||
private long lastRead = 0L;
|
private long lastRead = 0L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,6 +88,7 @@ public class DbSource {
|
||||||
defaultProps.lastModified());
|
defaultProps.lastModified());
|
||||||
url = props.getProperty(name + ".url");
|
url = props.getProperty(name + ".url");
|
||||||
driver = props.getProperty(name + ".driver");
|
driver = props.getProperty(name + ".driver");
|
||||||
|
isOracle = driver != null && driver.startsWith("oracle.jdbc.driver");
|
||||||
Class.forName(driver);
|
Class.forName(driver);
|
||||||
user = props.getProperty(name + ".user");
|
user = props.getProperty(name + ".user");
|
||||||
password = props.getProperty(name + ".password");
|
password = props.getProperty(name + ".password");
|
||||||
|
@ -118,4 +120,13 @@ public class DbSource {
|
||||||
public static void setDefaultProps(SystemProperties props) {
|
public static void setDefaultProps(SystemProperties props) {
|
||||||
defaultProps = props;
|
defaultProps = props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this an Oracle database?
|
||||||
|
*
|
||||||
|
* @return true if we're using an oracle JDBC driver
|
||||||
|
*/
|
||||||
|
public boolean isOracle() {
|
||||||
|
return isOracle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1201,6 +1201,8 @@ public final class NodeManager {
|
||||||
|
|
||||||
q.append(") ");
|
q.append(") ");
|
||||||
|
|
||||||
|
dbm.addJoinConstraints(q, " AND ");
|
||||||
|
|
||||||
if (rel.groupby != null) {
|
if (rel.groupby != null) {
|
||||||
q.append(rel.renderConstraints(home, home.getNonVirtualParent()));
|
q.append(rel.renderConstraints(home, home.getNonVirtualParent()));
|
||||||
|
|
||||||
|
@ -1504,6 +1506,8 @@ public final class NodeManager {
|
||||||
q.append(kstr);
|
q.append(kstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbm.addJoinConstraints(q, " AND ");
|
||||||
|
|
||||||
if (logSql) {
|
if (logSql) {
|
||||||
app.logEvent("### getNodeByKey: " + q.toString());
|
app.logEvent("### getNodeByKey: " + q.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -800,6 +800,8 @@ public final class Relation {
|
||||||
appendFilter(q, nonvirtual, prefix);
|
appendFilter(q, nonvirtual, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ownType.addJoinConstraints(q, prefix);
|
||||||
|
|
||||||
if (groupby != null) {
|
if (groupby != null) {
|
||||||
q.append(" GROUP BY " + groupby);
|
q.append(" GROUP BY " + groupby);
|
||||||
|
|
||||||
|
@ -912,8 +914,11 @@ public final class Relation {
|
||||||
/**
|
/**
|
||||||
* Render the constraints for this relation for use within
|
* Render the constraints for this relation for use within
|
||||||
* a left outer join select statement for the base object.
|
* a left outer join select statement for the base object.
|
||||||
|
*
|
||||||
|
* @param select the string buffer to write to
|
||||||
|
* @param isOracle create Oracle pre-9 style left outer join
|
||||||
*/
|
*/
|
||||||
public void renderJoinConstraints(StringBuffer select) {
|
public void renderJoinConstraints(StringBuffer select, boolean isOracle) {
|
||||||
for (int i = 0; i < constraints.length; i++) {
|
for (int i = 0; i < constraints.length; i++) {
|
||||||
select.append(ownType.getTableName());
|
select.append(ownType.getTableName());
|
||||||
select.append(".");
|
select.append(".");
|
||||||
|
@ -923,6 +928,11 @@ public final class Relation {
|
||||||
select.append(propName);
|
select.append(propName);
|
||||||
select.append(".");
|
select.append(".");
|
||||||
select.append(constraints[i].foreignName);
|
select.append(constraints[i].foreignName);
|
||||||
|
if (isOracle) {
|
||||||
|
// create old oracle style join - see
|
||||||
|
// http://www.praetoriate.com/oracle_tips_outer_joins.htm
|
||||||
|
select.append("(+)");
|
||||||
|
}
|
||||||
if (i == constraints.length-1) {
|
if (i == constraints.length-1) {
|
||||||
select.append(" ");
|
select.append(" ");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1062,6 +1072,7 @@ public final class Relation {
|
||||||
*/
|
*/
|
||||||
public void unsetConstraints(Node parent, INode child) {
|
public void unsetConstraints(Node parent, INode child) {
|
||||||
Node home = parent.getNonVirtualParent();
|
Node home = parent.getNonVirtualParent();
|
||||||
|
|
||||||
for (int i = 0; i < constraints.length; i++) {
|
for (int i = 0; i < constraints.length; i++) {
|
||||||
// don't set groupby constraints since we don't know if the
|
// don't set groupby constraints since we don't know if the
|
||||||
// parent node is the base node or a group node
|
// parent node is the base node or a group node
|
||||||
|
|
Loading…
Add table
Reference in a new issue