diff --git a/src/helma/objectmodel/db/DbMapping.java b/src/helma/objectmodel/db/DbMapping.java index e41c22ea..5f22585f 100644 --- a/src/helma/objectmodel/db/DbMapping.java +++ b/src/helma/objectmodel/db/DbMapping.java @@ -199,7 +199,6 @@ public class DbMapping implements Updatable { * completed on all other mappings in this application */ public synchronized void rewire () { - if (extendsProto != null) { parentMapping = app.getDbMapping (extendsProto); } @@ -236,42 +235,61 @@ public class DbMapping implements Updatable { prop2db = p2d; db2prop = d2p; - 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); - subnodesRel.update (subnodeMapping, props, version); + if (version == 1) { + String subnodeMapping = props.getProperty ("_children"); + if (subnodeMapping != null) { + try { + // check if subnode relation already exists. If so, reuse it + if (subnodesRel == null) + subnodesRel = new Relation (subnodeMapping, "_children", this, props); + subnodesRel.update (subnodeMapping, props, version); + if (subnodesRel.accessor != null) + propertiesRel = subnodesRel; - } catch (Exception x) { - app.logEvent ("Error reading _subnodes relation for "+typename+": "+x.getMessage ()); - // subnodesRel = null; - } - } else - subnodesRel = null; - - 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); - propertiesRel.update (propertiesMapping, props, version); - - // take over groupby flag from subnodes, if properties are subnodes - if (propertiesRel.subnodesAreProperties && subnodesRel != null) { - propertiesRel.groupby = subnodesRel.groupby; - propertiesRel.constraints = subnodesRel.constraints; - propertiesRel.filter = subnodesRel.filter; + } catch (Exception x) { + app.logEvent ("Error reading _subnodes relation for "+typename+": "+x.getMessage ()); + // subnodesRel = null; } + } else + subnodesRel = null; + } else { + 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); + subnodesRel.update (subnodeMapping, props, version); - } catch (Exception x) { - app.logEvent ("Error reading _properties relation for "+typename+": "+x.getMessage ()); - // propertiesRel = null; - } - } else - propertiesRel = null; + } catch (Exception x) { + app.logEvent ("Error reading _subnodes relation for "+typename+": "+x.getMessage ()); + // subnodesRel = null; + } + } else + subnodesRel = null; + + 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); + propertiesRel.update (propertiesMapping, props, version); + + // take over groupby flag from subnodes, if properties are subnodes + if (propertiesRel.subnodesAreProperties && subnodesRel != null) { + propertiesRel.groupby = subnodesRel.groupby; + propertiesRel.constraints = subnodesRel.constraints; + propertiesRel.filter = subnodesRel.filter; + } + + } catch (Exception x) { + app.logEvent ("Error reading _properties relation for "+typename+": "+x.getMessage ()); + // propertiesRel = null; + } + } else + propertiesRel = null; + } if (groupbyMapping != null) { initGroupbyMapping (); @@ -358,7 +376,7 @@ public class DbMapping implements Updatable { * Get the primary key column name for objects using this mapping. */ public String getIDField () { - if (idField == null && parentMapping != null) + if (idField == null && parentMapping != null) return parentMapping.getIDField (); return idField; } diff --git a/src/helma/objectmodel/db/Relation.java b/src/helma/objectmodel/db/Relation.java index c916ae95..7677649e 100644 --- a/src/helma/objectmodel/db/Relation.java +++ b/src/helma/objectmodel/db/Relation.java @@ -300,8 +300,7 @@ public class Relation { //////////////////////////////////////////////////////////////////////////////////////////// private void update_v1 (String desc, Properties props) { - boolean mountpoint = false; - Vector cnst = null; + Application app = ownType.getApplication (); if (desc == null || "".equals (desc.trim ())) { if (propName != null) { @@ -313,127 +312,50 @@ public class Relation { } } else { desc = desc.trim (); - String descLower = desc.toLowerCase (); - if (descLower.startsWith ("collection")) { - desc = desc.substring (10).trim (); - virtual = true; - } else if (descLower.startsWith ("[mountpoint]")) { - desc = desc.substring (12).trim (); - virtual = true; - mountpoint = true; + int open = desc.indexOf ("("); + int close = desc.indexOf (")"); + if (open > -1 && close > open) { + String ref = desc.substring (0, open).trim (); + String proto = desc.substring (open+1, close).trim (); + if ("collection".equalsIgnoreCase (ref)) { + virtual = !"_children".equalsIgnoreCase (propName); + reftype = COLLECTION; + } else if ("mountpoint".equalsIgnoreCase (ref)) { + virtual = true; + reftype = COLLECTION; + prototype = proto; + } else if ("object".equalsIgnoreCase (ref)) { + virtual = false; + reftype = REFERENCE; + } else { + throw new RuntimeException ("Invalid property Mapping: "+desc); + } + otherType = app.getDbMapping (proto); + if (otherType == null) + throw new RuntimeException ("DbMapping for "+proto+" not found from "+ownType.typename); } else { virtual = false; + columnName = desc; + reftype = PRIMITIVE; } - if (descLower.startsWith ("[readonly]")) { - desc = desc.substring (10).trim (); + String rdonly = props.getProperty (desc+".readonly"); + if (rdonly != null && "true".equalsIgnoreCase (rdonly)) { readonly = true; } else { readonly = false; } } - - // parse the basic properties of this mapping - parseMapping_v1 (desc, mountpoint); - - // the following options only apply to object relations + // the following options only apply to object and collection relations if (reftype != PRIMITIVE && reftype != INVALID) { - cnst = new Vector (); + Vector newConstraints = new Vector (); + parseOptions_v1 (newConstraints, props); - Constraint c = parseConstraint_v1 (desc); - - if (c != null) - cnst.add (c); - - parseOptions_v1 (cnst, props); - - constraints = new Constraint[cnst.size()]; - cnst.copyInto (constraints); - - // System.err.println ("PARSED RELATION "+this); - // if (accessor != null) - // System.err.println ("SET ACCESSOR: "+accessor); + constraints = new Constraint[newConstraints.size()]; + newConstraints.copyInto (constraints); } } - /** - * Parse a line describing a mapping of a property field. If the mapping is a - * object reference of a collection of objects, put any constraints in the Vector. - */ - protected void parseMapping_v1 (String desc, boolean mountpoint) { - - Application app = ownType.getApplication (); - - if (desc.indexOf ("<") > -1) { - reftype = COLLECTION; - int lt = desc.indexOf ("<"); - int dot = desc.indexOf ("."); - String other = dot < 0 ? desc.substring (lt+1).trim () : desc.substring (lt+1, dot).trim (); - otherType = app.getDbMapping (other); - if (otherType == null) - throw new RuntimeException ("DbMapping for "+other+" not found from "+ownType.typename); - columnName = null; - if (mountpoint) - prototype = other; - } else if (desc.indexOf (">") > -1) { - reftype = REFERENCE; - int bt = desc.indexOf (">"); - int dot = desc.indexOf ("."); - String other = dot > -1 ? desc.substring (bt+1, dot).trim () : desc.substring (bt+1).trim (); - otherType = app.getDbMapping (other); - if (otherType == null) - throw new RuntimeException ("DbMapping for "+other+" not found from "+ownType.typename); - columnName = desc.substring (0, bt).trim (); - if (mountpoint) - prototype = other; - } else if (desc.indexOf (".") > -1) { - reftype = COLLECTION; - int dot = desc.indexOf ("."); - String other = desc.substring (0, dot).trim (); - otherType = app.getDbMapping (other); - if (otherType == null) - throw new RuntimeException ("DbMapping for "+other+" not found from "+ownType.typename); - columnName = null; - // set accessor - accessor = desc.substring (dot+1).trim (); - if (mountpoint) - prototype = other; - } else { - if (virtual) { - reftype = COLLECTION; - otherType = app.getDbMapping (desc); - if (otherType == null) - throw new RuntimeException ("DbMapping for "+desc+" not found from "+ownType.typename); - if (mountpoint) - prototype = desc; - } else { - reftype = PRIMITIVE; - columnName = desc.trim (); - } - } - } - - - /** - * Parse a line describing a mapping of a property field. If the mapping is a - * object reference of a collection of objects, put any constraints in the Vector. - */ - protected Constraint parseConstraint_v1 (String desc) { - if (desc.indexOf ("<") > -1) { - int lt = desc.indexOf ("<"); - int dot = desc.indexOf ("."); - String remoteField = dot < 0 ? null : desc.substring (dot+1).trim (); - String localField = lt <= 0 ? null : desc.substring (0, lt).trim (); - return new Constraint (localField, otherType.getTableName (), remoteField, false); - } else if (desc.indexOf (">") > -1) { - int bt = desc.indexOf (">"); - int dot = desc.indexOf ("."); - String localField = desc.substring (0, bt).trim (); - String remoteField = dot < 0 ? null : desc.substring (dot+1).trim (); - return new Constraint (localField, otherType.getTableName (), remoteField, false); - } - return null; - } protected void parseOptions_v1 (Vector cnst, Properties props) { String loading = props.getProperty (propName+".loadmode"); @@ -470,13 +392,23 @@ public class Relation { aggressiveLoading = aggressiveCaching = false; } // check if subnode condition should be applied for property relations - if ("_properties".equalsIgnoreCase (propName) || virtual) { + accessor = props.getProperty (propName+".accessname"); + if (accessor != null) + subnodesAreProperties = true; + // parse contstraints + String local = props.getProperty (propName+".local"); + String foreign = props.getProperty (propName+".foreign"); + if (local != null && foreign != null) { + cnst.addElement (new Constraint (local, otherType.getTableName (), foreign, false)); + columnName = local; + } + /* if ("_properties".equalsIgnoreCase (propName) || virtual) { String subnodes2props = props.getProperty (propName+".aresubnodes"); subnodesAreProperties = "true".equalsIgnoreCase (subnodes2props); if (virtual) { String subnodefilter = props.getProperty (propName+".subnoderelation"); if (subnodefilter != null) { - Constraint c = parseConstraint_v1 (subnodefilter); + Constraint c = null; // parseConstraint_v1 (subnodefilter); if (c != null) { cnst.add (c); } @@ -488,7 +420,7 @@ public class Relation { virtualMapping.propertiesRel = getVirtualPropertyRelation (); virtualMapping.lastTypeChange = ownType.lastTypeChange; } - } + } */ } @@ -819,7 +751,7 @@ public class Relation { public void addToQuery (StringBuffer q, INode home, INode nonvirtual) throws SQLException { String local = null; INode ref = isGroupby ? home : nonvirtual; - if (localName == null) + if (localName == null || localName.equals (ref.getDbMapping ().getIDField ())) local = ref.getID (); else { String homeprop = ownType.columnNameToProperty (localName);