Use JDBC API directly for all queries. The only place where Village is still used is for inserts and updates.
This commit is contained in:
parent
4529071cf4
commit
dfc2431343
4 changed files with 207 additions and 132 deletions
|
@ -52,6 +52,10 @@ public final class DbMapping implements Updatable {
|
|||
HashMap prop2db;
|
||||
// Map of db columns to Relations objects
|
||||
HashMap db2prop;
|
||||
// prerendered list of columns to fetch from db
|
||||
String columns = null;
|
||||
// pre-rendered select statement
|
||||
String select = null;
|
||||
|
||||
// db field used as primary key
|
||||
private String idField;
|
||||
|
@ -135,7 +139,9 @@ public final class DbMapping implements Updatable {
|
|||
* for rewire to work, all other db mappings must have been initialized and registered.
|
||||
*/
|
||||
public synchronized void update () {
|
||||
|
||||
// reset columns
|
||||
columns = select = null;
|
||||
// read in properties
|
||||
table = props.getProperty ("_table");
|
||||
idgen = props.getProperty ("_idgen");
|
||||
// see if there is a field which specifies the prototype of objects, if different prototypes
|
||||
|
@ -564,19 +570,71 @@ public final class DbMapping implements Updatable {
|
|||
return schema;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a Village Schema object for this DbMapping.
|
||||
*/
|
||||
public synchronized String getColumns() throws ClassNotFoundException, SQLException {
|
||||
if (!isRelational ())
|
||||
throw new SQLException ("Can't get Schema for non-relational data mapping");
|
||||
if (source == null && parentMapping != null)
|
||||
return parentMapping.getColumns ();
|
||||
// Use local variable s to avoid synchronization (schema may be nulled elsewhere)
|
||||
if (columns == null) {
|
||||
// we do two things here: set the SQL type on the Relation mappings
|
||||
// and build a string of column names.
|
||||
Connection con = getConnection ();
|
||||
Statement stmt = con.createStatement ();
|
||||
ResultSet rs = stmt.executeQuery ("select * from "+getTableName()+" where 1 = 0");
|
||||
if (rs == null)
|
||||
throw new SQLException ("Error retrieving DB scheme for "+this);
|
||||
ResultSetMetaData meta = rs.getMetaData ();
|
||||
// ok, we have the meta data, now loop through mapping...
|
||||
// StringBuffer cbuffer = new StringBuffer (getIDField ());
|
||||
for (Iterator i=getDBPropertyIterator(); i.hasNext(); ) {
|
||||
Relation rel = (Relation) i.next ();
|
||||
if (rel.reftype != Relation.PRIMITIVE && rel.reftype != Relation.REFERENCE)
|
||||
continue;
|
||||
// cbuffer.append (",");
|
||||
// cbuffer.append (rel.getDbField());
|
||||
int idx = rs.findColumn (rel.getDbField());
|
||||
rel.setColumnType (meta.getColumnType (idx));
|
||||
}
|
||||
// columns = cbuffer.toString();
|
||||
columns = " * ";
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
public StringBuffer getSelect () throws SQLException, ClassNotFoundException {
|
||||
String sel = select;
|
||||
if (sel != null)
|
||||
return new StringBuffer (sel);
|
||||
StringBuffer s = new StringBuffer ("select ");
|
||||
s.append (getColumns ());
|
||||
s.append (" from ");
|
||||
s.append (table);
|
||||
s.append (" ");
|
||||
// cache rendered string for later calls.
|
||||
select = s.toString();
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if values for the column identified by the parameter need
|
||||
* to be quoted in SQL queries.
|
||||
*/
|
||||
public boolean needsQuotes (String columnName) throws SQLException {
|
||||
if (table == null && parentMapping != null)
|
||||
return parentMapping.needsQuotes (columnName);
|
||||
try {
|
||||
Schema s = getSchema ();
|
||||
if (s == null)
|
||||
Relation rel = (Relation) db2prop.get (columnName);
|
||||
if (rel == null)
|
||||
throw new SQLException ("Error retrieving relational schema for "+this);
|
||||
Column c = s.getColumn (columnName);
|
||||
if (c == null)
|
||||
throw new SQLException ("Column "+columnName+" not found in "+this);
|
||||
switch (c.typeEnum()) {
|
||||
// make sure columns are initialized and up to date
|
||||
if (columns == null)
|
||||
getColumns();
|
||||
switch (rel.getColumnType()) {
|
||||
case Types.CHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.LONGVARCHAR:
|
||||
|
|
|
@ -12,11 +12,11 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.io.*;
|
||||
import java.sql.Types;
|
||||
import java.sql.*;
|
||||
import helma.objectmodel.*;
|
||||
import helma.util.*;
|
||||
import helma.framework.IPathElement;
|
||||
import com.workingdogs.village.*;
|
||||
// import com.workingdogs.village.*;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -234,16 +234,15 @@ public final class Node implements INode, Serializable {
|
|||
/**
|
||||
* Constructor used for nodes being stored in a relational database table.
|
||||
*/
|
||||
public Node (DbMapping dbm, Record rec, WrappedNodeManager nmgr) throws DataSetException {
|
||||
public Node (DbMapping dbm, ResultSet rs, WrappedNodeManager nmgr) throws SQLException {
|
||||
|
||||
this.nmgr = nmgr;
|
||||
// see what prototype/DbMapping this object should use
|
||||
dbmap = dbm;
|
||||
String protoField= dbmap.getPrototypeField ();
|
||||
if (protoField != null) {
|
||||
Value val = rec.getValue (protoField);
|
||||
if (val != null && !val.isNull ()) {
|
||||
String protoName = val.asString ();
|
||||
String protoName = rs.getString (protoField);
|
||||
if (protoName != null) {
|
||||
dbmap = nmgr.getDbMapping (protoName);
|
||||
if (dbmap == null) {
|
||||
// invalid prototype name!
|
||||
|
@ -254,10 +253,10 @@ public final class Node implements INode, Serializable {
|
|||
}
|
||||
setPrototype (dbmap.getTypeName ());
|
||||
|
||||
id = rec.getValue (dbmap.getIDField ()).asString ();
|
||||
id = rs.getString (dbmap.getIDField ());
|
||||
// checkWriteLock ();
|
||||
String nameField = dbmap.getNameField ();
|
||||
name = nameField == null ? id : rec.getValue (nameField).asString ();
|
||||
name = nameField == null ? id : rs.getString (nameField);
|
||||
if (name == null || name.length() == 0)
|
||||
name = dbmap.getTypeName() + " " + id;
|
||||
// set parent for user objects to internal userroot node
|
||||
|
@ -276,60 +275,61 @@ public final class Node implements INode, Serializable {
|
|||
if (rel.reftype != Relation.PRIMITIVE && rel.reftype != Relation.REFERENCE)
|
||||
continue;
|
||||
|
||||
Value val = rec.getValue (rel.getDbField ());
|
||||
// Value val = rec.getValue (rel.getDbField ());
|
||||
|
||||
// if (val.isNull ())
|
||||
// continue;
|
||||
|
||||
Property newprop = new Property (rel.propName, this);
|
||||
|
||||
if (val.isNull ())
|
||||
newprop.setStringValue (null);
|
||||
else switch (val.type ()) {
|
||||
// if (val.isNull ())
|
||||
// newprop.setStringValue (null);
|
||||
// else
|
||||
switch (rel.getColumnType()) {
|
||||
|
||||
case Types.BIT:
|
||||
newprop.setBooleanValue (val.asBoolean());
|
||||
newprop.setBooleanValue (rs.getBoolean(rel.getDbField()));
|
||||
break;
|
||||
|
||||
case Types.TINYINT:
|
||||
case Types.BIGINT:
|
||||
case Types.SMALLINT:
|
||||
case Types.INTEGER:
|
||||
newprop.setIntegerValue (val.asLong());
|
||||
newprop.setIntegerValue (rs.getLong(rel.getDbField()));
|
||||
break;
|
||||
|
||||
case Types.REAL:
|
||||
case Types.FLOAT:
|
||||
case Types.DOUBLE:
|
||||
newprop.setFloatValue (val.asDouble());
|
||||
newprop.setFloatValue (rs.getDouble(rel.getDbField()));
|
||||
break;
|
||||
|
||||
case Types.DECIMAL:
|
||||
case Types.NUMERIC:
|
||||
java.math.BigDecimal num = val.asBigDecimal ();
|
||||
java.math.BigDecimal num = rs.getBigDecimal (rel.getDbField());
|
||||
if (num.scale() > 0)
|
||||
newprop.setFloatValue (val.asDouble());
|
||||
newprop.setFloatValue (rs.getDouble(rel.getDbField()));
|
||||
else
|
||||
newprop.setIntegerValue (val.asLong());
|
||||
newprop.setIntegerValue (rs.getLong(rel.getDbField()));
|
||||
break;
|
||||
|
||||
case Types.LONGVARBINARY:
|
||||
case Types.VARBINARY:
|
||||
case Types.BINARY:
|
||||
newprop.setStringValue (val.asString());
|
||||
newprop.setStringValue (rs.getString(rel.getDbField()));
|
||||
break;
|
||||
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.CHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.OTHER:
|
||||
newprop.setStringValue (val.asString());
|
||||
newprop.setStringValue (rs.getString(rel.getDbField()));
|
||||
break;
|
||||
|
||||
case Types.DATE:
|
||||
case Types.TIME:
|
||||
case Types.TIMESTAMP:
|
||||
newprop.setDateValue (val.asTimestamp());
|
||||
newprop.setDateValue (rs.getTimestamp(rel.getDbField()));
|
||||
break;
|
||||
|
||||
case Types.NULL:
|
||||
|
@ -338,10 +338,13 @@ public final class Node implements INode, Serializable {
|
|||
// continue;
|
||||
|
||||
default:
|
||||
newprop.setStringValue (val.asString());
|
||||
newprop.setStringValue (rs.getString(rel.getDbField()));
|
||||
break;
|
||||
}
|
||||
|
||||
if (rs.wasNull())
|
||||
newprop.setStringValue (null);
|
||||
|
||||
if(propMap == null)
|
||||
propMap = new Hashtable ();
|
||||
propMap.put (rel.propName.toLowerCase(), newprop);
|
||||
|
|
|
@ -601,26 +601,26 @@ public final class NodeManager {
|
|||
// Transactor tx = (Transactor) Thread.currentThread ();
|
||||
// tx.timer.beginEvent ("generateID "+map);
|
||||
|
||||
QueryDataSet qds = null;
|
||||
String retval = null;
|
||||
Statement stmt = null;
|
||||
try {
|
||||
Connection con = map.getConnection ();
|
||||
String q = "SELECT MAX("+map.getIDField()+") FROM "+map.getTableName();
|
||||
qds = new QueryDataSet (con, q);
|
||||
qds.fetchRecords ();
|
||||
stmt = con.createStatement ();
|
||||
ResultSet rs = stmt.executeQuery (q);
|
||||
// check for empty table
|
||||
if (qds.size () == 0) {
|
||||
if (!rs.next()) {
|
||||
long currMax = map.getNewID (0);
|
||||
retval = Long.toString (currMax);
|
||||
} else {
|
||||
long currMax = qds.getRecord (0).getValue (1).asLong ();
|
||||
long currMax = rs.getLong (1);
|
||||
currMax = map.getNewID (currMax);
|
||||
retval = Long.toString (currMax);
|
||||
}
|
||||
} finally {
|
||||
// tx.timer.endEvent ("generateID "+map);
|
||||
if (qds != null) try {
|
||||
qds.close ();
|
||||
if (stmt != null) try {
|
||||
stmt.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
return retval;
|
||||
|
@ -635,18 +635,18 @@ public final class NodeManager {
|
|||
// Transactor tx = (Transactor) Thread.currentThread ();
|
||||
// tx.timer.beginEvent ("generateID "+map);
|
||||
|
||||
QueryDataSet qds = null;
|
||||
Statement stmt = null;
|
||||
String retval = null;
|
||||
try {
|
||||
Connection con = map.getConnection ();
|
||||
String q = "SELECT "+map.getIDgen()+".nextval FROM dual";
|
||||
qds = new QueryDataSet (con, q);
|
||||
qds.fetchRecords ();
|
||||
retval = qds.getRecord (0).getValue (1).asString ();
|
||||
stmt = con.createStatement();
|
||||
ResultSet rs = stmt.executeQuery (q);
|
||||
retval = rs.getString (1);
|
||||
} finally {
|
||||
// tx.timer.endEvent ("generateID "+map);
|
||||
if (qds != null) try {
|
||||
qds.close ();
|
||||
if (stmt != null) try {
|
||||
stmt.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
return retval;
|
||||
|
@ -746,31 +746,31 @@ public final class NodeManager {
|
|||
List retval = new ArrayList ();
|
||||
DbMapping dbm = rel.otherType;
|
||||
|
||||
TableDataSet tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
||||
Connection con = dbm.getConnection ();
|
||||
Statement stmt = con.createStatement ();
|
||||
StringBuffer q = dbm.getSelect ();
|
||||
try {
|
||||
|
||||
if (home.getSubnodeRelation() != null) {
|
||||
// HACK: cut off the "where" part of manually set subnoderelation
|
||||
tds.where (home.getSubnodeRelation().trim().substring(5));
|
||||
q.append (home.getSubnodeRelation());
|
||||
} else {
|
||||
// let relation object build the query
|
||||
tds.where (rel.buildQuery (home, home.getNonVirtualParent (), null, "", false));
|
||||
q.append (" where ");
|
||||
q.append (rel.buildQuery (home, home.getNonVirtualParent (), null, "", false));
|
||||
if (rel.getOrder () != null)
|
||||
tds.order (rel.getOrder ());
|
||||
q.append (" "+rel.getOrder ());
|
||||
}
|
||||
|
||||
if (logSql)
|
||||
app.logEvent ("### getNodes: "+tds.getSelectString());
|
||||
app.logEvent ("### getNodes: "+q.toString());
|
||||
|
||||
if (rel.maxSize > 0)
|
||||
tds.fetchRecords (rel.maxSize);
|
||||
else
|
||||
tds.fetchRecords ();
|
||||
stmt.setMaxRows (rel.maxSize);
|
||||
|
||||
for (int i=0; i<tds.size (); i++) {
|
||||
ResultSet rs = stmt.executeQuery (q.toString ());
|
||||
|
||||
while (rs.next()) {
|
||||
// create new Nodes.
|
||||
Record rec = tds.getRecord (i);
|
||||
Node node = new Node (rel.otherType, rec, safe);
|
||||
Node node = new Node (rel.otherType, rs, safe);
|
||||
Key primKey = node.getKey ();
|
||||
retval.add (new NodeHandle (primKey));
|
||||
// do we need to synchronize on primKey here?
|
||||
|
@ -784,8 +784,8 @@ public final class NodeManager {
|
|||
|
||||
} finally {
|
||||
// tx.timer.endEvent ("getNodes "+home);
|
||||
if (tds != null) try {
|
||||
tds.close ();
|
||||
if (stmt != null) try {
|
||||
stmt.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
return retval;
|
||||
|
@ -804,42 +804,42 @@ public final class NodeManager {
|
|||
} else {
|
||||
int missing = cache.containsKeys (keys);
|
||||
if (missing > 0) {
|
||||
TableDataSet tds = new TableDataSet (dbm.getConnection (),
|
||||
dbm.getSchema (),
|
||||
dbm.getKeyDef ());
|
||||
Connection con = dbm.getConnection ();
|
||||
Statement stmt = con.createStatement ();
|
||||
StringBuffer q = dbm.getSelect ();
|
||||
try {
|
||||
String idfield = rel.groupby != null ? rel.groupby : dbm.getIDField ();
|
||||
boolean needsQuotes = dbm.needsQuotes (idfield);
|
||||
StringBuffer whereBuffer = new StringBuffer (idfield);
|
||||
whereBuffer.append (" in (");
|
||||
q.append (" where ");
|
||||
q.append (idfield);
|
||||
q.append (" in (");
|
||||
boolean first = true;
|
||||
for (int i=0; i<keys.length; i++) {
|
||||
if (keys[i] != null) {
|
||||
if (!first)
|
||||
whereBuffer.append (',');
|
||||
q.append (',');
|
||||
else
|
||||
first = false;
|
||||
if (needsQuotes) {
|
||||
whereBuffer.append ("'");
|
||||
whereBuffer.append (escape (keys[i].getID ()));
|
||||
whereBuffer.append ("'");
|
||||
q.append ("'");
|
||||
q.append (escape (keys[i].getID ()));
|
||||
q.append ("'");
|
||||
} else {
|
||||
whereBuffer.append (keys[i].getID ());
|
||||
q.append (keys[i].getID ());
|
||||
}
|
||||
}
|
||||
}
|
||||
whereBuffer.append (')');
|
||||
q.append (") ");
|
||||
if (rel.groupby != null) {
|
||||
whereBuffer.insert (0, rel.renderConstraints (home, home.getNonVirtualParent ()));
|
||||
q.append (rel.renderConstraints (home, home.getNonVirtualParent ()));
|
||||
if (rel.order != null)
|
||||
whereBuffer.append (" ORDER BY "+rel.order);
|
||||
q.append (" ORDER BY "+rel.order);
|
||||
}
|
||||
tds.where (whereBuffer.toString ());
|
||||
|
||||
if (logSql)
|
||||
app.logEvent ("### prefetchNodes: "+tds.getSelectString());
|
||||
app.logEvent ("### prefetchNodes: "+q.toString());
|
||||
|
||||
tds.fetchRecords ();
|
||||
ResultSet rs = stmt.executeQuery (q.toString());;
|
||||
|
||||
String groupbyProp = null;
|
||||
HashMap groupbySubnodes = null;
|
||||
|
@ -852,10 +852,9 @@ public final class NodeManager {
|
|||
if (rel.accessor != null && !rel.usesPrimaryKey ())
|
||||
accessProp = dbm.columnNameToProperty (rel.accessor);
|
||||
|
||||
for (int i=0; i<tds.size (); i++) {
|
||||
while (rs.next ()) {
|
||||
// create new Nodes.
|
||||
Record rec = tds.getRecord (i);
|
||||
Node node = new Node (dbm, rec, safe);
|
||||
Node node = new Node (dbm, rs, safe);
|
||||
Key primKey = node.getKey ();
|
||||
|
||||
// for grouped nodes, collect subnode lists for the intermediary
|
||||
|
@ -906,8 +905,8 @@ public final class NodeManager {
|
|||
}
|
||||
}
|
||||
} finally {
|
||||
if (tds != null) try {
|
||||
tds.close ();
|
||||
if (stmt != null) try {
|
||||
stmt.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
@ -933,7 +932,7 @@ public final class NodeManager {
|
|||
Connection con = rel.otherType.getConnection ();
|
||||
String table = rel.otherType.getTableName ();
|
||||
|
||||
QueryDataSet qds = null;
|
||||
Statement stmt = null;
|
||||
try {
|
||||
|
||||
String q = null;
|
||||
|
@ -948,18 +947,18 @@ public final class NodeManager {
|
|||
if (logSql)
|
||||
app.logEvent ("### countNodes: "+q);
|
||||
|
||||
qds = new QueryDataSet (con, q);
|
||||
stmt = con.createStatement();
|
||||
|
||||
qds.fetchRecords ();
|
||||
if (qds.size () == 0)
|
||||
ResultSet rs = stmt.executeQuery (q);
|
||||
if (!rs.next())
|
||||
retval = 0;
|
||||
else
|
||||
retval = qds.getRecord (0).getValue (1).asInt ();
|
||||
retval = rs.getInt (1);
|
||||
|
||||
} finally {
|
||||
// tx.timer.endEvent ("countNodes "+home);
|
||||
if (qds != null) try {
|
||||
qds.close ();
|
||||
if (stmt != null) try {
|
||||
stmt.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
return rel.maxSize > 0 ? Math.min (rel.maxSize, retval) : retval;
|
||||
|
@ -985,27 +984,26 @@ public final class NodeManager {
|
|||
Connection con = rel.otherType.getConnection ();
|
||||
String table = rel.otherType.getTableName ();
|
||||
|
||||
QueryDataSet qds = null;
|
||||
Statement stmt = null;
|
||||
|
||||
try {
|
||||
String q = "SELECT "+namefield+" FROM "+table+" ORDER BY "+namefield;
|
||||
qds = new QueryDataSet (con, q);
|
||||
stmt = con.createStatement ();
|
||||
|
||||
if (logSql)
|
||||
app.logEvent ("### getPropertyNames: "+qds.getSelectString());
|
||||
app.logEvent ("### getPropertyNames: "+q);
|
||||
|
||||
qds.fetchRecords ();
|
||||
for (int i=0; i<qds.size (); i++) {
|
||||
Record rec = qds.getRecord (i);
|
||||
String n = rec.getValue (1).asString ();
|
||||
ResultSet rs = stmt.executeQuery (q);
|
||||
while (rs.next()) {
|
||||
String n = rs.getString (1);
|
||||
if (n != null)
|
||||
retval.addElement (n);
|
||||
}
|
||||
|
||||
} finally {
|
||||
// tx.timer.endEvent ("getNodeIDs "+home);
|
||||
if (qds != null) try {
|
||||
qds.close ();
|
||||
if (stmt != null) try {
|
||||
stmt.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
return retval;
|
||||
|
@ -1031,26 +1029,31 @@ public final class NodeManager {
|
|||
} else {
|
||||
String idfield =dbm.getIDField ();
|
||||
|
||||
TableDataSet tds = null;
|
||||
Statement stmt = null;
|
||||
try {
|
||||
tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
||||
tds.where (idfield+" = "+kstr);
|
||||
Connection con = dbm.getConnection ();
|
||||
stmt = con.createStatement ();
|
||||
|
||||
StringBuffer q = dbm.getSelect ();
|
||||
q.append (" where ");
|
||||
q.append (idfield);
|
||||
q.append (" = ");
|
||||
q.append (kstr);
|
||||
|
||||
if (logSql)
|
||||
app.logEvent ("### getNodeByKey: "+tds.getSelectString());
|
||||
app.logEvent ("### getNodeByKey: "+q.toString());
|
||||
|
||||
tds.fetchRecords ();
|
||||
ResultSet rs = stmt.executeQuery (q.toString());
|
||||
|
||||
if (tds.size () == 0)
|
||||
if (!rs.next ())
|
||||
return null;
|
||||
if (tds.size () > 1)
|
||||
if (!rs.isLast ())
|
||||
throw new RuntimeException ("More than one value returned by query.");
|
||||
Record rec = tds.getRecord (0);
|
||||
node = new Node (dbm, rec, safe);
|
||||
node = new Node (dbm, rs, safe);
|
||||
|
||||
} finally {
|
||||
if (tds != null) try {
|
||||
tds.close ();
|
||||
if (stmt != null) try {
|
||||
stmt.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
@ -1086,35 +1089,35 @@ public final class NodeManager {
|
|||
return node;
|
||||
|
||||
} else {
|
||||
TableDataSet tds = null;
|
||||
Statement stmt = null;
|
||||
try {
|
||||
DbMapping dbm = rel.otherType;
|
||||
|
||||
tds = new TableDataSet (dbm.getConnection (), dbm.getSchema (), dbm.getKeyDef ());
|
||||
|
||||
Connection con = dbm.getConnection ();
|
||||
StringBuffer q = dbm.getSelect ();
|
||||
if (home.getSubnodeRelation () != null) {
|
||||
// combine our key with the constraints in the manually set subnode relation
|
||||
StringBuffer where = new StringBuffer ();
|
||||
where.append (rel.accessor);
|
||||
where.append (" = '");
|
||||
where.append (escape(kstr));
|
||||
where.append ("' AND ");
|
||||
where.append (home.getSubnodeRelation ().trim().substring(5).trim());
|
||||
tds.where (where.toString ());
|
||||
} else
|
||||
tds.where (rel.buildQuery (home, home.getNonVirtualParent (), kstr, "", false));
|
||||
|
||||
q.append (home.getSubnodeRelation ());
|
||||
q.append (" and ");
|
||||
q.append (rel.accessor);
|
||||
q.append (" = '");
|
||||
q.append (escape(kstr));
|
||||
q.append ("'");
|
||||
} else {
|
||||
q.append (" where ");
|
||||
q.append (rel.buildQuery (home, home.getNonVirtualParent (), kstr, "", false));
|
||||
}
|
||||
if (logSql)
|
||||
app.logEvent ("### getNodeByRelation: "+tds.getSelectString());
|
||||
app.logEvent ("### getNodeByRelation: "+q.toString());
|
||||
|
||||
tds.fetchRecords ();
|
||||
stmt = con.createStatement ();
|
||||
ResultSet rs = stmt.executeQuery (q.toString());
|
||||
|
||||
if (tds.size () == 0)
|
||||
if (!rs.next ())
|
||||
return null;
|
||||
if (tds.size () > 1)
|
||||
if (!rs.isLast ())
|
||||
throw new RuntimeException ("More than one value returned by query.");
|
||||
Record rec = tds.getRecord (0);
|
||||
node = new Node (rel.otherType, rec, safe);
|
||||
node = new Node (rel.otherType, rs, safe);
|
||||
|
||||
// Check if node is already cached with primary Key.
|
||||
if (!rel.usesPrimaryKey()) {
|
||||
|
@ -1126,8 +1129,8 @@ public final class NodeManager {
|
|||
}
|
||||
|
||||
} finally {
|
||||
if (tds != null) try {
|
||||
tds.close ();
|
||||
if (stmt != null) try {
|
||||
stmt.close ();
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ public final class Relation {
|
|||
// the DbMapping of the prototype we link to, unless this is a "primitive" (non-object) relation
|
||||
DbMapping otherType;
|
||||
|
||||
// the column type, as defined in java.sql.Types
|
||||
int columnType;
|
||||
|
||||
// if this relation defines a virtual node, we need to provide a DbMapping for these virtual nodes
|
||||
DbMapping virtualMapping;
|
||||
|
||||
|
@ -240,6 +243,14 @@ public final class Relation {
|
|||
return propName;
|
||||
}
|
||||
|
||||
public void setColumnType (int ct) {
|
||||
columnType = ct;
|
||||
}
|
||||
|
||||
public int getColumnType () {
|
||||
return columnType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a constraint to the current list of constraints
|
||||
|
|
Loading…
Add table
Reference in a new issue