further cleaned up things around DbMapping and Relation - more to come
This commit is contained in:
parent
e8f3e04637
commit
18e3d82166
4 changed files with 171 additions and 79 deletions
|
@ -37,11 +37,14 @@ public class DbMapping implements Updatable {
|
|||
|
||||
ParentInfo[] parent; // list of properties to try for parent
|
||||
|
||||
DbMapping subnodes;
|
||||
DbMapping properties;
|
||||
// DbMapping subnodes;
|
||||
// DbMapping properties;
|
||||
Relation subnodesRel;
|
||||
Relation propertiesRel;
|
||||
|
||||
// if this defines a subnode mapping with groupby layer, we need a DbMapping for those groupby nodes
|
||||
DbMapping groupbyMapping;
|
||||
|
||||
// Map of property names to Relations objects
|
||||
Hashtable prop2db;
|
||||
// Map of db columns to Relations objects
|
||||
|
@ -88,8 +91,8 @@ public class DbMapping implements Updatable {
|
|||
db2prop = new Hashtable ();
|
||||
|
||||
parent = null;
|
||||
subnodes = null;
|
||||
properties = null;
|
||||
// subnodes = null;
|
||||
// properties = null;
|
||||
idField = "id";
|
||||
}
|
||||
|
||||
|
@ -105,8 +108,8 @@ public class DbMapping implements Updatable {
|
|||
db2prop = new Hashtable ();
|
||||
|
||||
parent = null;
|
||||
subnodes = null;
|
||||
properties = null;
|
||||
// subnodes = null;
|
||||
// properties = null;
|
||||
idField = "id";
|
||||
|
||||
this.props = props;
|
||||
|
@ -191,9 +194,16 @@ public class DbMapping implements Updatable {
|
|||
try {
|
||||
if (!propName.startsWith ("_") && propName.indexOf (".") < 0) {
|
||||
String dbField = props.getProperty (propName);
|
||||
Relation rel = new Relation (dbField, propName, this, props);
|
||||
// check if a relation for this propery already exists. If so, reuse it
|
||||
Relation rel = propertyToRelation (propName);
|
||||
if (rel == null)
|
||||
rel = new Relation (dbField, propName, this, props);
|
||||
else
|
||||
rel.update (dbField, props);
|
||||
p2d.put (propName, rel);
|
||||
if (rel.localField != null)
|
||||
if (rel.localField != null &&
|
||||
(rel.direction == Relation.PRIMITIVE ||
|
||||
rel.direction == Relation.FORWARD))
|
||||
d2p.put (rel.localField, rel);
|
||||
// app.logEvent ("Mapping "+propName+" -> "+dbField);
|
||||
}
|
||||
|
@ -208,14 +218,18 @@ public class DbMapping implements Updatable {
|
|||
String subnodeMapping = props.getProperty ("_subnodes");
|
||||
if (subnodeMapping != null) {
|
||||
try {
|
||||
// check if subnode relation already exists. If so, reuse it
|
||||
if (subnodesRel == null)
|
||||
subnodesRel = new Relation (subnodeMapping, "_subnodes", this, props);
|
||||
if (subnodesRel.isReference ())
|
||||
subnodes = subnodesRel.other;
|
||||
else
|
||||
subnodes = (DbMapping) app.getDbMapping (subnodeMapping);
|
||||
subnodesRel.update (subnodeMapping, props);
|
||||
// if (subnodesRel.isReference ())
|
||||
// subnodes = subnodesRel.other;
|
||||
// else
|
||||
// subnodes = (DbMapping) app.getDbMapping (subnodeMapping);
|
||||
} catch (Exception x) {
|
||||
app.logEvent ("Error in type.properties: "+x.getMessage ());
|
||||
subnodesRel = null;
|
||||
app.logEvent ("Error reading _subnodes relation for "+typename+": "+x.getMessage ());
|
||||
// subnodesRel = null;
|
||||
}
|
||||
} else
|
||||
subnodesRel = null;
|
||||
|
@ -223,22 +237,30 @@ public class DbMapping implements Updatable {
|
|||
String propertiesMapping = props.getProperty ("_properties");
|
||||
if (propertiesMapping != null) {
|
||||
try {
|
||||
// check if property relation already exists. If so, reuse it
|
||||
if (propertiesRel == null)
|
||||
propertiesRel = new Relation (propertiesMapping, "_properties", this, props);
|
||||
if (propertiesRel.isReference ())
|
||||
properties = propertiesRel.other;
|
||||
else
|
||||
properties = (DbMapping) app.getDbMapping (propertiesMapping);
|
||||
propertiesRel.update (propertiesMapping, props);
|
||||
// if (propertiesRel.isReference ())
|
||||
// properties = propertiesRel.other;
|
||||
// else
|
||||
// properties = (DbMapping) app.getDbMapping (propertiesMapping);
|
||||
// take over groupby flag from subnodes, if properties are subnodes
|
||||
if (propertiesRel.subnodesAreProperties && subnodesRel != null)
|
||||
propertiesRel.groupby = subnodesRel.groupby;
|
||||
} catch (Exception x) {
|
||||
app.logEvent ("Error in type.properties: "+x.getMessage ());
|
||||
propertiesRel = null;
|
||||
app.logEvent ("Error reading _properties relation for "+typename+": "+x.getMessage ());
|
||||
// propertiesRel = null;
|
||||
}
|
||||
} else
|
||||
propertiesRel = null;
|
||||
|
||||
// app.logEvent ("rewiring: "+this);
|
||||
if (groupbyMapping != null) {
|
||||
groupbyMapping.subnodesRel = subnodesRel == null ? null : subnodesRel.getGroupbySubnodeRelation ();
|
||||
groupbyMapping.propertiesRel = propertiesRel == null ? null : propertiesRel.getGroupbyPropertyRelation ();
|
||||
groupbyMapping.lastTypeChange = this.lastTypeChange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -323,21 +345,46 @@ public class DbMapping implements Updatable {
|
|||
/**
|
||||
* Translate a database column name to an object property name according to this mapping.
|
||||
*/
|
||||
public Relation columnNameToProperty (String columnName) {
|
||||
public String columnNameToProperty (String columnName) {
|
||||
if (table == null && parentMapping != null)
|
||||
return parentMapping.columnNameToProperty (columnName);
|
||||
Relation rel = (Relation) db2prop.get (columnName);
|
||||
if (rel != null && (rel.direction == Relation.PRIMITIVE || rel.direction == Relation.FORWARD))
|
||||
return rel.propname;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate an object property name to a database column name according to this mapping.
|
||||
*/
|
||||
public String propertyToColumnName (String propName) {
|
||||
if (table == null && parentMapping != null)
|
||||
return parentMapping.propertyToColumnName (propName);
|
||||
Relation rel = (Relation) prop2db.get (propName);
|
||||
if (rel != null && (rel.direction == Relation.PRIMITIVE || rel.direction == Relation.FORWARD))
|
||||
return rel.localField;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a database column name to an object property name according to this mapping.
|
||||
*/
|
||||
public Relation columnNameToRelation (String columnName) {
|
||||
if (table == null && parentMapping != null)
|
||||
return parentMapping.columnNameToRelation (columnName);
|
||||
return (Relation) db2prop.get (columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate an object property name to a database column name according to this mapping.
|
||||
*/
|
||||
public Relation propertyToColumnName (String propName) {
|
||||
public Relation propertyToRelation (String propName) {
|
||||
if (table == null && parentMapping != null)
|
||||
return parentMapping.propertyToColumnName (propName);
|
||||
return parentMapping.propertyToRelation (propName);
|
||||
return (Relation) prop2db.get (propName);
|
||||
}
|
||||
|
||||
|
||||
public synchronized ParentInfo[] getParentInfo () {
|
||||
if (parent == null && parentMapping != null)
|
||||
return parentMapping.getParentInfo ();
|
||||
|
@ -346,14 +393,13 @@ public class DbMapping implements Updatable {
|
|||
|
||||
|
||||
public DbMapping getSubnodeMapping () {
|
||||
if (subnodes == null && parentMapping != null)
|
||||
if (subnodesRel != null)
|
||||
return subnodesRel.other;
|
||||
if (parentMapping != null)
|
||||
return parentMapping.getSubnodeMapping ();
|
||||
return subnodes;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setSubnodeMapping (DbMapping sm) {
|
||||
subnodes = sm;
|
||||
}
|
||||
|
||||
public DbMapping getExactPropertyMapping (String propname) {
|
||||
if (propname == null)
|
||||
|
@ -365,8 +411,13 @@ public class DbMapping implements Updatable {
|
|||
}
|
||||
|
||||
public DbMapping getPropertyMapping (String propname) {
|
||||
if (propname == null)
|
||||
return properties;
|
||||
if (propname == null) {
|
||||
if (propertiesRel != null)
|
||||
return propertiesRel.other;
|
||||
if (parentMapping != null)
|
||||
return parentMapping.getPropertyMapping (null);
|
||||
}
|
||||
|
||||
Relation rel = (Relation) prop2db.get (propname.toLowerCase());
|
||||
if (rel != null) {
|
||||
// if this is a virtual node, it doesn't have a dbmapping
|
||||
|
@ -376,15 +427,31 @@ public class DbMapping implements Updatable {
|
|||
return rel.other;
|
||||
}
|
||||
|
||||
if (properties == null && parentMapping != null)
|
||||
if (propertiesRel != null)
|
||||
return propertiesRel.other;
|
||||
if (parentMapping != null)
|
||||
return parentMapping.getPropertyMapping (propname);
|
||||
|
||||
return properties;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setPropertyMapping (DbMapping pm) {
|
||||
public DbMapping getGroupbyMapping () {
|
||||
if (subnodesRel == null || subnodesRel.groupby == null)
|
||||
return null;
|
||||
if (groupbyMapping == null) {
|
||||
groupbyMapping = new DbMapping ();
|
||||
groupbyMapping.subnodesRel = subnodesRel.getGroupbySubnodeRelation ();
|
||||
if (propertiesRel != null)
|
||||
groupbyMapping.propertiesRel = propertiesRel.getGroupbyPropertyRelation ();
|
||||
else
|
||||
groupbyMapping.propertiesRel = subnodesRel.getGroupbyPropertyRelation ();
|
||||
groupbyMapping.typename = subnodesRel.prototype;
|
||||
}
|
||||
return groupbyMapping;
|
||||
}
|
||||
|
||||
/* public void setPropertyMapping (DbMapping pm) {
|
||||
properties = pm;
|
||||
}
|
||||
} */
|
||||
|
||||
public void setSubnodeRelation (Relation rel) {
|
||||
subnodesRel = rel;
|
||||
|
|
|
@ -44,6 +44,15 @@ public class DbSource {
|
|||
// false here and make commit/rollback invocations in Transactor methods;
|
||||
IServer.getLogger().log ("Created new Connection to "+url);
|
||||
tx.registerConnection (this, con);
|
||||
//////////////////////////////////////////////
|
||||
/* DatabaseMetaData meta = con.getMetaData ();
|
||||
ResultSet tables = meta.getCatalogs ();
|
||||
while (tables.next())
|
||||
System.err.println ("********* TABLE: "+ tables.getObject (1));
|
||||
ResultSet types = meta.getTypeInfo ();
|
||||
while (types.next())
|
||||
System.err.println ("******* TYPE: "+types.getObject(1) +" - "+types.getObject(2)+" - "+types.getObject(6));
|
||||
*/
|
||||
}
|
||||
return con;
|
||||
}
|
||||
|
|
|
@ -393,9 +393,7 @@ public class Node implements INode, Serializable {
|
|||
// node.setState (TRANSIENT);
|
||||
// make a db mapping good enough that the virtual node finds its subnodes
|
||||
DbMapping dbm = new DbMapping ();
|
||||
dbm.setSubnodeMapping (rel.other);
|
||||
dbm.setSubnodeRelation (rel);
|
||||
dbm.setPropertyMapping (rel.other);
|
||||
dbm.setPropertyRelation (rel);
|
||||
node.setDbMapping (dbm);
|
||||
setNode (propname, node);
|
||||
|
|
|
@ -13,15 +13,27 @@ import java.util.Properties;
|
|||
*/
|
||||
public class Relation {
|
||||
|
||||
// TODO: explain hop mapping types
|
||||
// these constants define different type of property-to-db-mappings
|
||||
|
||||
// there is an error in the description of this relation
|
||||
public final static int INVALID = -1;
|
||||
// a mapping of a non-object, scalar type
|
||||
public final static int PRIMITIVE = 0;
|
||||
// a 1-to-1 relation, i.e. a field in the table is a foreign key to another object
|
||||
public final static int FORWARD = 1;
|
||||
// a 1-to-many relation, a field in another table points to objects of this type
|
||||
public final static int BACKWARD = 2;
|
||||
// direct mapping is a very powerful feature: objects of some types can be directly accessed
|
||||
// by one of their properties/db fields.
|
||||
public final static int DIRECT = 3;
|
||||
|
||||
// the DbMapping of the type we come from
|
||||
public DbMapping home;
|
||||
// the DbMapping of the prototype we link to, unless this is a "primitive" (non-object) relation
|
||||
public DbMapping other;
|
||||
// if this relation defines a virtual node, we need a DbMapping for these virtual nodes
|
||||
DbMapping virtualMapping;
|
||||
|
||||
public String propname;
|
||||
protected String localField, remoteField;
|
||||
public int direction;
|
||||
|
@ -34,31 +46,39 @@ public class Relation {
|
|||
public String order;
|
||||
public String groupbyorder;
|
||||
public String groupby;
|
||||
public String dogroupby;
|
||||
public String prototype;
|
||||
public String groupbyprototype;
|
||||
public String filter;
|
||||
|
||||
Relation subnoderelation = null; // additional relation used to filter subnodes
|
||||
Relation subnoderelation = null; // additional relation used to filter subnodes for virtual nodes
|
||||
|
||||
/**
|
||||
* This constructor is used to directly construct a Relation, as opposed to reading it from a proerty file
|
||||
* This constructor makes a copy of an existing relation. Not all fields are copied, just those
|
||||
* which are needed in groupby- and virtual nodes defined by this relation.
|
||||
*/
|
||||
public Relation (DbMapping other, String localField, String remoteField, int direction, boolean subnodesAreProperties) {
|
||||
this.other = other;
|
||||
this.localField = localField;
|
||||
this.remoteField = remoteField;
|
||||
this.direction = direction;
|
||||
this.subnodesAreProperties = subnodesAreProperties;
|
||||
public Relation (Relation rel) {
|
||||
this.home = rel.home;
|
||||
this.other = rel.other;
|
||||
this.localField = rel.localField;
|
||||
this.remoteField = rel.remoteField;
|
||||
this.direction = rel.direction;
|
||||
this.subnodesAreProperties = rel.subnodesAreProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a relation entry from a line in a properties file.
|
||||
*/
|
||||
public Relation (String desc, String propname, DbMapping home, Properties props) {
|
||||
|
||||
this.home = home;
|
||||
this.propname = propname;
|
||||
other = null;
|
||||
|
||||
update (desc, props);
|
||||
}
|
||||
|
||||
public void update (String desc, Properties props) {
|
||||
|
||||
Application app = home.getApplication ();
|
||||
boolean mountpoint = false;
|
||||
|
||||
|
@ -179,6 +199,12 @@ public class Relation {
|
|||
subnoderelation.order = order;
|
||||
}
|
||||
}
|
||||
// update virtual mapping, if it already exists
|
||||
if (virtualMapping != null) {
|
||||
virtualMapping.subnodesRel = getVirtualSubnodeRelation ();
|
||||
virtualMapping.propertiesRel = getVirtualPropertyRelation ();
|
||||
virtualMapping.lastTypeChange = home.lastTypeChange;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,23 +226,6 @@ public class Relation {
|
|||
return subnoderelation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a key string to cache a node with a specific value for this relation. If the
|
||||
* Relation uses the primary key return just the key value, otherwise include info on the
|
||||
* used column or even the base node to avoid collisions.
|
||||
*/
|
||||
/* public String getKeyID (INode home, String kval) {
|
||||
// if the column is not the primary key, we add the column name to the key
|
||||
if ((direction == DIRECT || direction == FORWARD) && !usesPrimaryKey ()) {
|
||||
// check if the subnode relation also has to be considered
|
||||
if (subnodesAreProperties)
|
||||
return "["+home.getID()+"]"+remoteField+"="+kval; // HACK
|
||||
else
|
||||
return remoteField+"="+kval;
|
||||
} else {
|
||||
return kval;
|
||||
}
|
||||
} */
|
||||
|
||||
/**
|
||||
* Get the local column name for this relation to use in where clauses of select statements.
|
||||
|
@ -247,18 +256,29 @@ public class Relation {
|
|||
return remoteField;
|
||||
}
|
||||
|
||||
public DbMapping getVirtualMapping () {
|
||||
if (!virtual)
|
||||
return null;
|
||||
if (virtualMapping == null) {
|
||||
virtualMapping = new DbMapping ();
|
||||
virtualMapping.subnodesRel = getVirtualSubnodeRelation ();
|
||||
virtualMapping.propertiesRel = getVirtualPropertyRelation ();
|
||||
}
|
||||
return virtualMapping;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a Relation that defines the subnodes of a virtual node.
|
||||
*/
|
||||
public Relation getVirtualSubnodeRelation () {
|
||||
Relation getVirtualSubnodeRelation () {
|
||||
if (!virtual)
|
||||
throw new RuntimeException ("getVirtualSubnodeRelation called on non-virtual relation");
|
||||
Relation vr = null;
|
||||
if (subnoderelation != null)
|
||||
vr = subnoderelation.makeClone ();
|
||||
vr = new Relation (subnoderelation);
|
||||
else
|
||||
vr = makeClone ();
|
||||
vr = new Relation (this);
|
||||
vr.groupby = groupby;
|
||||
vr.groupbyorder = groupbyorder;
|
||||
vr.groupbyprototype = groupbyprototype;
|
||||
|
@ -273,10 +293,10 @@ public class Relation {
|
|||
/**
|
||||
* Return a Relation that defines the properties of a virtual node.
|
||||
*/
|
||||
public Relation getVirtualPropertyRelation () {
|
||||
Relation getVirtualPropertyRelation () {
|
||||
if (!virtual)
|
||||
throw new RuntimeException ("getVirtualPropertyRelation called on non-virtual relation");
|
||||
Relation vr = makeClone ();
|
||||
Relation vr = new Relation (this);
|
||||
vr.groupby = groupby;
|
||||
vr.groupbyorder = groupbyorder;
|
||||
vr.groupbyprototype = groupbyprototype;
|
||||
|
@ -289,37 +309,35 @@ public class Relation {
|
|||
/**
|
||||
* Return a Relation that defines the subnodes of a group-by node.
|
||||
*/
|
||||
public Relation getGroupbySubnodeRelation () {
|
||||
Relation getGroupbySubnodeRelation () {
|
||||
if (groupby == null)
|
||||
throw new RuntimeException ("getGroupbySubnodeRelation called on non-group-by relation");
|
||||
Relation vr = null;
|
||||
if (subnoderelation != null)
|
||||
vr = subnoderelation.makeClone ();
|
||||
vr = new Relation (subnoderelation);
|
||||
else
|
||||
vr = makeClone ();
|
||||
vr = new Relation (this);
|
||||
vr.order = order;
|
||||
vr.prototype = groupbyprototype;
|
||||
vr.filter = filter;
|
||||
vr.dogroupby = groupby;
|
||||
return vr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Relation that defines the properties of a group-by node.
|
||||
*/
|
||||
public Relation getGroupbyPropertyRelation () {
|
||||
Relation getGroupbyPropertyRelation () {
|
||||
if (groupby == null)
|
||||
throw new RuntimeException ("getGroupbyPropertyRelation called on non-group-by relation");
|
||||
Relation vr = makeClone ();
|
||||
Relation vr = new Relation (this);
|
||||
vr.order = order;
|
||||
vr.prototype = groupbyprototype;
|
||||
vr.filter = filter;
|
||||
vr.dogroupby = groupby;
|
||||
return vr;
|
||||
}
|
||||
|
||||
public Relation makeClone () {
|
||||
return new Relation (other, localField, remoteField, direction, subnodesAreProperties);
|
||||
}
|
||||
|
||||
|
||||
public String toString () {
|
||||
return "Relation["+home+">"+other+"]";
|
||||
|
|
Loading…
Add table
Reference in a new issue