diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.classpath b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.classpath new file mode 100644 index 00000000000..b3c4139fc5b --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.classpath @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.gitignore b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.gitignore new file mode 100644 index 00000000000..fcc7e7a559b --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.gitignore @@ -0,0 +1,6 @@ +target +bin +build +*.xcodeproj +*.pbxproj +ant.* \ No newline at end of file diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.project b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.project new file mode 100644 index 00000000000..264c3e865b9 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/.project @@ -0,0 +1,23 @@ + + + OpenBaseWOPKPlugIn + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.objectstyle.wolips.incrementalbuilder + + + + + + org.eclipse.jdt.core.javanature + org.objectstyle.wolips.incrementalframeworknature + + diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Resources/Properties b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Resources/Properties new file mode 100644 index 00000000000..e69de29bb2d diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InQualifier.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InQualifier.java new file mode 100644 index 00000000000..755ede30502 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InQualifier.java @@ -0,0 +1,301 @@ +package com.openbase.webobjects.qualifiers; +// +// InQualifier.java +// +// Much thanks to the Wonder guys and Pierre Bernard for their helpful examples +// +// The in qualifier allows qualification on an attribute that is contained in a list of values. This qualifier +// supports both in-memory and sql based qualification. +// +// The SQL generated is of the form: "VALUE IN (XX, YY, ZZ)" +// +// Created by Alex Cone on 12/16/05. +// Copyright (c) 2005 __MyCompanyName__. All rights reserved. +// + +import com.webobjects.foundation.*; +import com.webobjects.eoaccess.*; +import com.webobjects.eocontrol.*; +import java.util.*; +import org.apache.log4j.*; + +public class InQualifier extends EOKeyValueQualifier implements EOQualifierEvaluation, Cloneable { + protected static Logger LOGGER = Logger.getLogger(InQualifier.class.getName()); + + private static final String InKeyword = " IN "; + + private String _key = null; + private NSArray _values = null; + + /** register SQL generation support for the qualifier */ + static { + EOQualifierSQLGeneration.Support.setSupportForClass(new InQualifierSQLGenerationSupport(), InQualifier.class); + } + + public static String allButLastPathComponent(String path) { + int i = path.lastIndexOf(NSKeyValueCodingAdditions.KeyPathSeparator); + return (i < 0) ? null : path.substring(0, i); + } + + public static String lastPathComponent(String path) { + int i = path.lastIndexOf(NSKeyValueCodingAdditions.KeyPathSeparator); + return (i < 0) ? path : path.substring(i + 1); + } + + public InQualifier(String aKey, NSArray values) { + // Just to make EOKeyValueQualifier happy + super(aKey, EOQualifier.QualifierOperatorEqual, values); + this.setKey(aKey); + this.setValues(values); + } + + public String key() { + return _key; + } + + public void setKey(String aValue) { + _key = aValue; + } + + public NSArray values() { + return _values; + } + + public void setValues(NSArray anArray) { + _values = anArray; + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + + buffer.append("("); + buffer.append(key()); + buffer.append(InKeyword); + buffer.append("("); + + Enumeration e = values().objectEnumerator(); + while (e.hasMoreElements()) { + Object object = e.nextElement(); + + if (object == NSKeyValueCoding.NullValue) { + buffer.append("null"); + } else if (object instanceof Number) { + buffer.append(object); + } else if (object instanceof EOQualifierVariable) { + buffer.append("$"); + buffer.append(((EOQualifierVariable) object).key()); + } else { + buffer.append("'"); + buffer.append(object); + buffer.append("'"); + } + if (e.hasMoreElements()) { + buffer.append(", "); + } + } + buffer.append("))"); + return buffer.toString(); + } + + public void addQualifierKeysToSet(NSMutableSet aSet) { + if (aSet != null) { + String aKey = this.key(); + if (aKey != null) { + aSet.addObject(aKey); + } + } + } + + public boolean evaluateWithObject(Object object) { + Object value = NSKeyValueCodingAdditions.Utility.valueForKeyPath(object, key()); + if (value == null) { + value = NSKeyValueCoding.NullValue; + } + return values().containsObject(value); + } + + // we don't do bindings + public EOQualifier qualifierWithBindings(NSDictionary someBindings, boolean requiresAll) { + return (EOQualifier) this.clone(); + } + // we don't do validation + public void validateKeysWithRootClassDescription(EOClassDescription aClassDescription) { + super.validateKeysWithRootClassDescription(aClassDescription); + } + + + public static class InQualifierSQLGenerationSupport extends EOQualifierSQLGeneration.Support { + + public InQualifierSQLGenerationSupport() { + super(); + } + + public String sqlStringForSQLExpression(EOQualifier eoqualifier, EOSQLExpression aSQLExpression) { + String sqlString = null; + if ((aSQLExpression != null) && (aSQLExpression.entity() != null)) { + InQualifier inQualifier = (InQualifier)eoqualifier; + EOEntity anEntity = aSQLExpression.entity(); + String aKey = inQualifier.key(); + NSArray aValuesArray = inQualifier.values(); + + if ((aKey != null) && (aValuesArray != null) && (aValuesArray.count() > 0)) { + StringBuffer sb = new StringBuffer(); + EOAttribute keyAttr = attributeForPath(anEntity, aKey); + String attributeString = aSQLExpression.sqlStringForAttribute(keyAttr); + sb.append(aSQLExpression.formatSQLString(attributeString, keyAttr.readFormat())); + sb.append(InQualifier.InKeyword); + sb.append("("); + + for (int i = 0; i < aValuesArray.count(); i++ ) { + EOKeyValueQualifier containsQualifier = new EOKeyValueQualifier(aKey, EOQualifier.QualifierOperatorContains, + aValuesArray.objectAtIndex(i)); + containsQualifier = (EOKeyValueQualifier) anEntity.schemaBasedQualifier(containsQualifier); + if ( i > 0 ) { + sb.append(", "); + } + sb.append(aSQLExpression.sqlStringForValue(containsQualifier.value(), containsQualifier.key())); + } + sb.append(")"); + sqlString = sb.toString(); + } + } + return sqlString; + } + + public EOQualifier schemaBasedQualifierWithRootEntity(EOQualifier qualifier, EOEntity entity) { + InQualifier inQualifier = (InQualifier) qualifier; + String keyPath = inQualifier.key(); + EORelationship relationship = relationshipForPath(entity, keyPath); + + if (relationship != null) { + if (relationship.isFlattened()) { + relationship = (EORelationship) relationship.componentRelationships().lastObject(); + } + // just handle single key joins for now + EOJoin join = (EOJoin)relationship.joins().objectAtIndex(0); + String destAttributeName = join.destinationAttribute().name(); + String optimizedPath = optimizeQualifierKeyPath(entity, keyPath, destAttributeName); + + NSMutableSet newValues = new NSMutableSet(inQualifier.values().count()); + Enumeration values = inQualifier.values().objectEnumerator(); + + while (values.hasMoreElements()) { + Object value = values.nextElement(); + + if (value == NSKeyValueCoding.NullValue || (value instanceof EOQualifierVariable)) { + newValues.addObject(value); + } else { + EOEnterpriseObject enterpriseObject = (EOEnterpriseObject) value; + EOObjectStoreCoordinator objectStoreCoordinator = + (EOObjectStoreCoordinator) enterpriseObject.editingContext().rootObjectStore(); + NSDictionary destValues = + objectStoreCoordinator.valuesForKeys(new NSArray(destAttributeName), enterpriseObject); + Object destVal = destValues.objectForKey(destAttributeName); + newValues.addObject((destVal != null ? destVal: NSKeyValueCoding.NullValue)); + } + } + return nullValueAwareQualifier(new InQualifier(optimizedPath, newValues.allObjects())); + } else { + return nullValueAwareQualifier(inQualifier); + } + } + + public EOQualifier qualifierMigratedFromEntityRelationshipPath(EOQualifier eoqualifier, EOEntity eoentity, String s) { + // the key migration is the same as for EOKeyValueQualifier + InQualifier inQualifier=(InQualifier)eoqualifier; + return new InQualifier(_translateKeyAcrossRelationshipPath(inQualifier.key(), s, eoentity), inQualifier.values()); + } + + // Protected instance methods + protected EOQualifier nullValueAwareQualifier(InQualifier inQualifier) { + if (inQualifier.values().containsObject(NSKeyValueCoding.NullValue)) { + EOQualifier nullQual = new EOKeyValueQualifier(inQualifier.key(), EOQualifier.QualifierOperatorEqual, NSKeyValueCoding.NullValue); + NSSet aSet = new NSSet(inQualifier.values()); + NSSet noNullSet = aSet.setBySubtractingSet(new NSSet(NSKeyValueCoding.NullValue)); + EOQualifier noNullQual = new InQualifier(inQualifier.key(), noNullSet.allObjects()); + return new EOOrQualifier(new NSArray(new Object[] { nullQual, noNullQual })); + } else { + return inQualifier; + } + } + + protected EOAttribute attributeForPath(EOEntity entity, String keyPath) { + if (keyPath != null) { + StringTokenizer tokenizer = new StringTokenizer(keyPath, NSKeyValueCodingAdditions.KeyPathSeparator); + EORelationship relationship = null; + while (tokenizer.hasMoreElements()) { + String key = tokenizer.nextToken(); + if (tokenizer.hasMoreElements()) { + relationship = entity.anyRelationshipNamed(key); + } else { + EOAttribute attribute = entity.anyAttributeNamed(key); + if (attribute == null) { + relationship = entity.anyRelationshipNamed(key); + if (relationship != null) { + if (relationship.isFlattened()) { + relationship = (EORelationship) relationship.componentRelationships().lastObject(); + } + // just handle single key joins for now + EOJoin join = (EOJoin)relationship.joins().objectAtIndex(0); + return join.sourceAttribute(); + } + } + } + if (relationship != null) { + entity = relationship.destinationEntity(); + } else { + return null; + } + } + return null; + } + return null; + } + + protected EORelationship relationshipForPath(EOEntity entity, String keyPath) { + if (keyPath != null) { + StringTokenizer tokenizer = new StringTokenizer(keyPath, NSKeyValueCodingAdditions.KeyPathSeparator); + EORelationship relationship = null; + while (tokenizer.hasMoreElements()) { + String key = tokenizer.nextToken(); + relationship = entity.anyRelationshipNamed(key); + if (relationship != null) { + entity = relationship.destinationEntity(); + } else { + return null; + } + } + return relationship; + } + return null; + } + + protected String optimizeQualifierKeyPath(EOEntity entity, String keyPath, String attributeName) { + if ((keyPath == null) || (keyPath.length() == 0)) { + return attributeName; + } else { + EORelationship relationship = (entity == null) ? null : relationshipForPath(entity, keyPath); + if (relationship != null) { + NSArray joins = relationship.joins(); + int joinCount = (joins == null) ? 0 : joins.count(); + for (int i = joinCount - 1; i >= 0; i--) { + EOJoin join = (EOJoin) joins.objectAtIndex(i); + if (join.destinationAttribute().name().equals(attributeName)) { + String newPath = allButLastPathComponent(keyPath); + String newAttributeName = join.sourceAttribute().name(); + return optimizeQualifierKeyPath(entity, newPath, newAttributeName); + } + } + } + return (keyPath + NSKeyValueCodingAdditions.KeyPathSeparator + attributeName); + } + } + + } + + // cloning support + public Object clone() { + return new InQualifier(this.key(), this.values()); + } + +} diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InSubqueryQualifier.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InSubqueryQualifier.java new file mode 100644 index 00000000000..03ffc57199e --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/openbase/webobjects/qualifiers/InSubqueryQualifier.java @@ -0,0 +1,279 @@ +package com.openbase.webobjects.qualifiers; +// +// InSubqueryQualifier.java +// +// Much thanks to the Wonder guys and Pierre Bernard for their helpful examples +// +// Created by Alex Cone on 12/18/05. +// Copyright (c) 2005 __MyCompanyName__. All rights reserved. +// + +import com.webobjects.foundation.*; +import com.webobjects.eoaccess.*; +import com.webobjects.eocontrol.*; + +import java.util.*; +import java.lang.reflect.*; + +import org.apache.log4j.*; + +public class InSubqueryQualifier extends EOQualifier implements EOQualifierEvaluation, Cloneable { + protected static Logger LOGGER = Logger.getLogger(InQualifier.class.getName()); + + private static final String InKeyword = " IN "; + + /** Path to an attribute or relationship of the qualified entity + */ + protected String _key; + + /** Name of the entity from which to get values to match against + */ + protected String _entityName; + + /** Name of the attribute in the destination entity to match against + */ + protected String _attributePath; + + /** Qualifier to limit the list of acceptable values + */ + protected EOQualifier _subQualifier; + + /** register SQL generation support for the qualifier */ + static { + EOQualifierSQLGeneration.Support.setSupportForClass(new InSubqueryQualifierSQLGenerationSupport(), InSubqueryQualifier.class); + } + + /** Constructor for queries off an attribute. + * + * @param key key path to an attribute of the qualified entity + * @param entityName name of the entity from which to get values to match against + * @param attributePath name of the attribute in the destination entity to match against + * @param subQualifier qualifier to limit the list of acceptable values + */ + public InSubqueryQualifier(String key, String entityName, String attributePath, EOQualifier subQualifier) { + if ((key == null) || (entityName == null) || (attributePath == null)) { + throw new IllegalArgumentException("Arguments key, entityName and attributePath may not be null"); + } + this.setKey(key); + this.setEntityName(entityName); + this.setAttributePath(attributePath); + this.setSubQualifier(subQualifier); + } + + /** Constructor for queries off a relationship + * + * @param key key path to a relationship of the qualified entity + * @param subQualifier qualifier to limit the list of acceptable values + */ + public InSubqueryQualifier(String key, EOQualifier subQualifier) { + if (key == null) { + throw new IllegalArgumentException("Argument key may not be null"); + } + this.setKey(key); + this.setSubQualifier(subQualifier); + } + + public String key() { + return _key; + } + + public void setKey(String aValue) { + _key = aValue; + } + + public String entityName() { + return _entityName; + } + + public void setEntityName(String aValue) { + _entityName = aValue; + } + + public String attributePath() { + return _attributePath; + } + + public void setAttributePath(String aValue) { + _attributePath = aValue; + } + + public EOQualifier subQualifier() { + return _subQualifier; + } + + public void setSubQualifier(EOQualifier aValue) { + _subQualifier = aValue; + } + + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append("("); + buffer.append(key()); + buffer.append(InKeyword); + buffer.append("("); + buffer.append(" SELECT "); + buffer.append((attributePath() != null) ? attributePath() : "*"); + + if (entityName() != null) { + buffer.append(" FROM "); + buffer.append(entityName()); + } + if (subQualifier() != null) { + buffer.append(" WHERE "); + buffer.append(subQualifier().toString()); + } + buffer.append(")"); + return buffer.toString(); + } + + public void addQualifierKeysToSet(NSMutableSet keySet) { + keySet.addObject(key()); + if (subQualifier() != null) { + NSMutableSet subKeySet = new NSMutableSet(); + subQualifier().addQualifierKeysToSet(subKeySet); + if (entityName() == null) { + Enumeration subKeys = subKeySet.objectEnumerator(); + String prefix = key() + NSKeyValueCodingAdditions.KeyPathSeparator; + while (subKeys.hasMoreElements()) { + keySet.addObject(prefix + subKeys.nextElement()); + } + } else { + keySet.addObjectsFromArray(subKeySet.allObjects()); + } + } + } + + // we don't do bindings yet + public EOQualifier qualifierWithBindings(NSDictionary someBindings, boolean requiresAll) { + return (EOQualifier) this.clone(); + } + // we don't do validation + public void validateKeysWithRootClassDescription(EOClassDescription aClassDescription) { + } + + public Object clone() { + return new InSubqueryQualifier(key(), entityName(), attributePath(), subQualifier()); + } + + public static class InSubqueryQualifierSQLGenerationSupport extends EOQualifierSQLGeneration.Support { + + public InSubqueryQualifierSQLGenerationSupport() { + super(); + } + + public String sqlStringForSQLExpression(EOQualifier eoqualifier, EOSQLExpression aSQLExpression) { + String sqlString = null; + if ((aSQLExpression != null) && (aSQLExpression.entity() != null)) { + InSubqueryQualifier isQualifier = (InSubqueryQualifier)eoqualifier; + EOEntity anEntity = aSQLExpression.entity(); + String aKey = isQualifier.key(); + + StringBuffer sb = new StringBuffer(); + String attributeString = aSQLExpression.sqlStringForAttributeNamed(aKey); + sb.append(aSQLExpression.formatSQLString(attributeString, attributeForPath(anEntity, aKey).readFormat())); + sb.append(InSubqueryQualifier.InKeyword); + sb.append("("); + + EOEntity subEntity = anEntity.model().modelGroup().entityNamed(isQualifier.entityName()); + + EODatabaseContext context = EODatabaseContext.registeredDatabaseContextForModel(subEntity.model(), + EOObjectStoreCoordinator.defaultCoordinator()); + EOSQLExpressionFactory factory = context.database().adaptor().expressionFactory(); + EOSQLExpression subExpression = factory.expressionForEntity(subEntity); + + // EOSQLExpression subExpression = expressionForEntity(subEntity); + EOFetchSpecification subFetch = new EOFetchSpecification(subEntity.name(), isQualifier.subQualifier(), null); + String attributePath = isQualifier.attributePath(); + NSArray subAttributes; + if (attributePath != null) { + subAttributes = new NSArray(attributeForPath(subEntity, attributePath)); + } else { + subAttributes = subEntity.primaryKeyAttributes(); + } + + StringBuffer subBuffer = new StringBuffer(); + + subExpression.aliasesByRelationshipPath().setObjectForKey("t1", ""); + subExpression.setUseAliases(true); + subExpression.prepareSelectExpressionWithAttributes(subAttributes, false, subFetch); + + subBuffer.append("SELECT "); + subBuffer.append(subExpression.listString()); + subBuffer.append(" FROM "); + subBuffer.append(subExpression.tableListWithRootEntity(subEntity)); + + boolean hasWhereClause = ((subExpression.whereClauseString() != null) && + (subExpression.whereClauseString().length() > 0)); + if (hasWhereClause) { + subBuffer.append(" WHERE "); + subBuffer.append(subExpression.whereClauseString()); + } + if ((subExpression.joinClauseString() != null) + && (subExpression.joinClauseString().length() > 0)) { + if (hasWhereClause) { + subBuffer.append(" AND "); + } + subBuffer.append(subExpression.joinClauseString()); + } + String subquerySqlString = subBuffer.toString(); + sb.append(subquerySqlString.replaceAll("t0.", "t1.")); + sb.append(")"); + sqlString = sb.toString(); + + Enumeration bindVariables = subExpression.bindVariableDictionaries().objectEnumerator(); + while (bindVariables.hasMoreElements()) { + aSQLExpression.addBindVariableDictionary((NSDictionary) bindVariables.nextElement()); + } + + } + return sqlString; + } + + public EOQualifier schemaBasedQualifierWithRootEntity(EOQualifier qualifier, EOEntity entity) { + return qualifier; + } + + public EOQualifier qualifierMigratedFromEntityRelationshipPath(EOQualifier eoqualifier, EOEntity eoentity, String s) { + // the key migration is the same as for EOKeyValueQualifier + InSubqueryQualifier isQualifier=(InSubqueryQualifier)eoqualifier; + return new InSubqueryQualifier(_translateKeyAcrossRelationshipPath(isQualifier.key(), s, eoentity), + isQualifier.entityName(), isQualifier.attributePath(), isQualifier.subQualifier() ); + } + + + // Protected instance methods + protected EOAttribute attributeForPath(EOEntity entity, String keyPath) { + if (keyPath != null) { + StringTokenizer tokenizer = new StringTokenizer(keyPath, NSKeyValueCodingAdditions.KeyPathSeparator); + EORelationship relationship = null; + while (tokenizer.hasMoreElements()) { + String key = tokenizer.nextToken(); + if (tokenizer.hasMoreElements()) { + relationship = entity.anyRelationshipNamed(key); + } else { + return entity.anyAttributeNamed(key); + } + if (relationship != null) { + entity = relationship.destinationEntity(); + } else { + return null; + } + } + return null; + } + return null; + } + + protected EOSQLExpression expressionForEntity(EOEntity entity) { + try { + Class expressionClass = ((EOAdaptor)EOAdaptor.adaptorWithModel(entity.model())).expressionClass(); + Constructor constructor = expressionClass.getConstructor(new Class[] { EOEntity.class }); + EOSQLExpression expression = (EOSQLExpression)constructor.newInstance(new Object[] { entity }); + return expression; + } catch (Exception exception) { + throw new NSForwardException(exception); + } + } + + } +} diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/EROpenBasePlugIn.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/EROpenBasePlugIn.java new file mode 100644 index 00000000000..6d37e90ef12 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/EROpenBasePlugIn.java @@ -0,0 +1,9 @@ +package com.webobjects.jdbcadaptor; + +public class EROpenBasePlugIn extends _OpenBasePlugIn { + + public EROpenBasePlugIn(JDBCAdaptor adaptor) { + super(adaptor); + } + +} diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/OpenBasePKPlugIn.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/OpenBasePKPlugIn.java new file mode 100644 index 00000000000..b3c053c99fe --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/OpenBasePKPlugIn.java @@ -0,0 +1,87 @@ +package com.webobjects.jdbcadaptor; + +import com.webobjects.eoaccess.*; +import com.webobjects.jdbcadaptor.*; +import com.webobjects.foundation.*; + + + +public class OpenBasePKPlugIn extends _OpenBasePlugIn{ + + public OpenBasePKPlugIn(JDBCAdaptor adaptor){ + super(adaptor); + //System.out.println("In OpenBasePKPlugIn constructor...: "); + } + + public NSArray newPrimaryKeys(int count, EOEntity entity, JDBCChannel adaptorChannel){ +// System.out.println("newPrimaryKeys called with: Count -> " + count + " EOEntity -> " + entity); + NSMutableArray result = new NSMutableArray(); + if(count > 0){ + // Make sure the chonnel is open + if ( !adaptorChannel.isOpen() ) { + adaptorChannel.openChannel(); + } + // Get the external table name + String tableName = entity.externalName(); + // Get the primary key attributes + NSArray primaryKeyAttributeNamesArray = entity.primaryKeyAttributes(); + + // If NEWID isn't appropriate, fall back to the super class's implementation + if (primaryKeyAttributeNamesArray.count() != 1) { + return super.newPrimaryKeys(count, entity, adaptorChannel); + } + + EOAttribute column = (EOAttribute)primaryKeyAttributeNamesArray.objectAtIndex(0); + String attributeName = column.name(); // the EOF name + // Get the external primarey key name + String columnName = column.columnName(); // the database name + + + NSMutableDictionary row; + // Loop to get count new PKs + while(0 < count) { + // Create the SQL query to get a new PK + String newidSQL; + + if (count > 100) { + newidSQL = "NEWID FOR " + tableName + " " + columnName + " 100 "; + } else { + newidSQL = "NEWID FOR " + tableName + " " + columnName + " " + count; + } + + adaptorChannel.evaluateExpression(adaptorChannel.adaptorContext().adaptor().expressionFactory().expressionForString(newidSQL)); + adaptorChannel.setAttributesToFetch(adaptorChannel.describeResults()); + // if success do this.... + while ( (row = adaptorChannel.fetchRow()) != null ) { + Object newPK = row.objectForKey(columnName.toUpperCase()); + result.addObject(new NSDictionary(newPK, attributeName)); + count = count - 1; + } + // otherwise, if there is an SQL error, break out of the loop + } + if (count!=0) { + //create a global variable to hold the unique key + String varName = "unique_" + tableName + "_" + columnName; + String newidSQL = "INCREMENT " + varName; + + while(0 < count) { + adaptorChannel.evaluateExpression(adaptorChannel.adaptorContext().adaptor().expressionFactory().expressionForString(newidSQL)); + adaptorChannel.setAttributesToFetch(adaptorChannel.describeResults()); + + if ( (row = adaptorChannel.fetchRow()) != null ) { + Object newPK = row.objectForKey(columnName.toUpperCase()); + result.addObject(new NSDictionary(newPK, attributeName)); + count = count - 1; + } else { + String createSQL = "DECLARE GLOBAL " + varName + " AS INTEGER INITIALIZE 1 SILENT "; + String messageSQL = "ALERT WARNING 'WO PK Generation: Initialize global variable " + varName + " with seed value at system startup."; + adaptorChannel.evaluateExpression(adaptorChannel.adaptorContext().adaptor().expressionFactory().expressionForString(createSQL)); + adaptorChannel.evaluateExpression(adaptorChannel.adaptorContext().adaptor().expressionFactory().expressionForString(messageSQL)); + } + // we need to do some error checking here so if it fails the second time through it does not continue to try creating the global variable. + } + } + } + return result; + } +} \ No newline at end of file diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/_OpenBasePlugIn.java b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/_OpenBasePlugIn.java new file mode 100644 index 00000000000..d62b31a7964 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/Sources/com/webobjects/jdbcadaptor/_OpenBasePlugIn.java @@ -0,0 +1,516 @@ +// +// OpenBasePlugIn.java +// +// Copyright 2004 OpenBase International Ltd. All rights reserved. +// +package com.webobjects.jdbcadaptor; + +import com.webobjects.eoaccess.EOAdaptor; +import com.webobjects.eoaccess.EOAttribute; +import com.webobjects.eoaccess.EOQualifierSQLGeneration; +import com.webobjects.eoaccess.EORelationship; +import com.webobjects.eoaccess.EOSQLExpression; +import com.webobjects.eoaccess.EOEntity; +import com.webobjects.eoaccess.synchronization.EOSchemaGeneration; +import com.webobjects.eoaccess.synchronization.EOSchemaGenerationOptions; +import com.webobjects.eoaccess.synchronization.EOSchemaSynchronization; +import com.webobjects.eoaccess.synchronization.EOSchemaSynchronizationColumnChanges; +import com.webobjects.eoaccess.synchronization.EOSchemaSynchronizationFactory; +import com.webobjects.eoaccess.synchronization.EOSchemaSynchronizationModelChanges; +import com.webobjects.eocontrol.*; +import com.webobjects.foundation.*; + +import java.util.*; +import java.sql.*; + +public class _OpenBasePlugIn extends JDBCPlugIn { + + public static class OpenBaseExpression extends JDBCExpression { + + /** + * Fetch spec limit ivar + */ + private int _fetchLimit; + + public OpenBaseExpression(EOEntity entity) { + super(entity); + _rtrimFunctionName = null; + } + + public char sqlEscapeChar() { + return '\0'; + } + + public String sqlStringForCaseInsensitiveLike(String valueString, String keyString) { + return _NSStringUtilities.concat( keyString, " LIKE ", valueString); + } + + public String assembleSelectStatementWithAttributes(NSArray attributes, boolean lock, EOQualifier qualifier, NSArray fetchOrder, String selectString, String columnList, String tableList, String whereClause, String joinClause, String orderByClause, String lockClause) { + StringBuffer statement = new StringBuffer(2048); + statement.append(selectString); + statement.append(columnList); + statement.append(" FROM "); + statement.append(tableList); + if(lockClause != null && lockClause.length() != 0) { + statement.append(" "); + statement.append(lockClause); + } + if(whereClause != null && whereClause.length() != 0) { + statement.append(" WHERE "); + statement.append(whereClause); + } + if(joinClause != null && joinClause.length() != 0) { + if(whereClause != null && whereClause.length() != 0) + statement.append(" AND "); + else + statement.append(" WHERE "); + statement.append(joinClause); + } + if(orderByClause != null && orderByClause.length() != 0) { + statement.append(" ORDER BY "); + statement.append(orderByClause); + } + if (_fetchLimit != 0) { + statement.append(" RETURN RESULTS "); + statement.append(_fetchLimit); + } + return statement.toString(); + } + + public String assembleJoinClause(String leftName, String rightName, int semantic) { + switch(semantic) { + case EORelationship.FullOuterJoin: // '\001' + throw new JDBCAdaptorException("OpenBase does not support full outer joins: unable to join " + leftName + " and " + rightName, null); + + case EORelationship.LeftOuterJoin: // '\002' + return leftName + " * " + rightName; + + case EORelationship.RightOuterJoin: // '\003' + throw new JDBCAdaptorException("OpenBase does not support right outer joins: unable to join " + leftName + " and " + rightName, null); + } + return super.assembleJoinClause(leftName, rightName, semantic); + } + + public void prepareSelectExpressionWithAttributes(NSArray nsarray, boolean flag, EOFetchSpecification eofetchspecification) { + if(!eofetchspecification.promptsAfterFetchLimit()) { + _fetchLimit = eofetchspecification.fetchLimit(); + } + super.prepareSelectExpressionWithAttributes(nsarray, flag, eofetchspecification); + } + + // ------------------------- + // CREATE INSERT STATEMENT + // ------------------------- + + public void prepareInsertExpressionWithRow(NSDictionary row) { + EOAttribute attribute; + Object value; + for(Enumeration enumeration = row.keyEnumerator(); enumeration.hasMoreElements(); this.addInsertListAttribute(attribute, value)) { + String attributeName = (String)enumeration.nextElement(); + attribute = this.entity().anyAttributeNamed(attributeName); + if(attribute == null) + throw new IllegalStateException("prepareInsertExpressionWithRow: row argument contains key '" + attributeName + "' which does not have corresponding attribute on entity '" + this.entity().name() + "'"); + value = row.objectForKey(attributeName); + } + + String tableList = tableListWithRootEntity(_rootEntityForExpression()); + _statement = this.assembleInsertStatementWithRow(row, tableList, new String(_listString), new String(_valueListString)); + } + + // [PJYF Nov 5 2004] + // This is major Hack to generate a diffenrent bind dictionary for update and insert form the one for select and delete + public String assembleInsertStatementWithRow(NSDictionary row, String tableList, String columnList, String valueList) { + if(columnList != null) + return _NSStringUtilities.concat("INSERT INTO ", tableList, "(", columnList, ")", " VALUES ", "(", valueList, ")"); + else + return _NSStringUtilities.concat("INSERT INTO ", tableList, " VALUES ", "(", valueList, ")"); + } + + // [PJYF Nov 5 2004] + // This is major Hack to generate a diffenrent bind dictionary for update and insert form the one for select and delete + public void addInsertListAttribute(EOAttribute attribute, Object value) { + this.appendItemToListString(this.sqlStringForAttribute(attribute), this._listString()); + String attributeValue = this.sqlStringForForInsertOrUpdateValue(value, attribute.name()); + attributeValue = this.formatSQLString(attributeValue, attribute.writeFormat()); + this.appendItemToListString(attributeValue, _valueList()); + } + + // ------------------------- + // CREATE UPDATE STATEMENT + // ------------------------- + + public void prepareUpdateExpressionWithRow(NSDictionary row, EOQualifier qualifier) { + EOAttribute attribute; + Object value; + for(Enumeration enumeration = row.keyEnumerator(); enumeration.hasMoreElements(); addUpdateListAttribute(attribute, value)) { + String attributeName = (String)enumeration.nextElement(); + attribute = this.entity().anyAttributeNamed(attributeName); + if(attribute == null) + throw new IllegalStateException("prepareUpdateExpressionWithRow: row argument contains key '" + attributeName + "' which does not have corresponding attribute on entity '" + this.entity().name() + "'"); + value = row.objectForKey(attributeName); + } + + _whereClauseString = EOQualifierSQLGeneration.Support._sqlStringForSQLExpression(qualifier, this); + String tableList = tableListWithRootEntity(_rootEntityForExpression()); + _statement = assembleUpdateStatementWithRow(row, qualifier, tableList, new String(_listString), _whereClauseString); + } + + public String assembleUpdateStatementWithRow(NSDictionary row, EOQualifier qualifier, String tableList, String updateList, String whereClause) { + return _NSStringUtilities.concat("UPDATE ", tableList, " SET ", updateList, " WHERE ", whereClause); + } + + // [PJYF Nov 5 2004] + // This is major Hack to generate a diffenrent bind dictionary for update and insert form the one for select and delete + public void addUpdateListAttribute(EOAttribute attribute, Object value) { + String attributeName = this.sqlStringForAttribute(attribute); + String attributeValue = this.sqlStringForForInsertOrUpdateValue(value, attribute.name()); + attributeValue = this.formatSQLString(attributeValue, attribute.writeFormat()); + this.appendItemToListString(_NSStringUtilities.concat(attributeName, " = ", attributeValue), this._listString()); + } + + // [PJYF Nov 5 2004] + // This is major Hack to generate a diffenrent bind dictionary for update and insert form the one for select and delete + public String sqlStringForForInsertOrUpdateValue(Object value, String keyPath) { + EOAttribute attribute = this.entity()._attributeForPath(keyPath); + if(value != NSKeyValueCoding.NullValue && (useBindVariables() && this.shouldUseBindVariableForAttribute(attribute) || this.mustUseBindVariableForAttribute(attribute))) { + NSMutableDictionary bindVariableDictionary = this.bindVariableDictionaryForAttribute(attribute, value); + this.addBindVariableDictionary(bindVariableDictionary); + return (String)bindVariableDictionary.objectForKey(BindVariablePlaceHolderKey); + } else { + return this.formatValueForAttribute(value, attribute); + } + } + + // [PJYF Nov 5 2004] + // We need to prepend the question mark with a type attribute to get the jdbc driver to do the right thing. + // @ (Object) T (Text) or B (Binary) + public NSMutableDictionary bindVariableDictionaryForInsertOrUpdateAttribute(EOAttribute attribute, Object value) { + String prepend = ""; + String externalType = ( attribute.externalType() != null ? attribute.externalType().toLowerCase() : ""); + if ( "binary".equals(externalType) ) { + prepend = "B"; + } else if ( "text".equals(externalType) ) { + prepend = "T"; + } else if ( "object".equals(externalType) ) { + prepend = "@"; + } + return new NSMutableDictionary(new Object[] { attribute.name(), prepend + "?", attribute, value }, new Object[] { BindVariableNameKey, BindVariablePlaceHolderKey, BindVariableAttributeKey, BindVariableValueKey }); + } + + // [PJYF Oct 19 2004] + // We need to prepend the question mark with a type attribute to get the jdbc driver to do the right thing. + // only for B (Binary) + public NSMutableDictionary bindVariableDictionaryForAttribute(EOAttribute attribute, Object value) { + String prepend = ""; + String externalType = ( attribute.externalType() != null ? attribute.externalType().toLowerCase() : ""); + if ( "binary".equals(externalType) ) { + prepend = "B"; + } + return new NSMutableDictionary(new Object[] { attribute.name(), prepend + "?", attribute, value }, new Object[] { BindVariableNameKey, BindVariablePlaceHolderKey, BindVariableAttributeKey, BindVariableValueKey }); + } + } + + public static class OpenBaseSynchronizationFactory extends EOSchemaSynchronizationFactory implements EOSchemaGeneration { + + public OpenBaseSynchronizationFactory(EOAdaptor adaptor) { + super(adaptor); + } + + public NSArray dropPrimaryKeySupportStatementsForEntityGroups(NSArray entityGroups) { + return new NSArray(this._expressionForString("DROP TABLE " + ((JDBCAdaptor)this.adaptor()).plugIn().primaryKeyTableName() )); + } + + public NSArray foreignKeyConstraintStatementsForRelationship(EORelationship relationship) { + System.err.println("trying to run this but we're returning an empty array"); + return NSArray.EmptyArray; + } + + public NSArray primaryKeySupportStatementsForEntityGroups(NSArray entityGroups) { + String primaryKeyTableName = ((JDBCAdaptor)this.adaptor()).plugIn().primaryKeyTableName(); + NSMutableArray primaryKeyExpressions = new NSMutableArray(); + primaryKeyExpressions.addObject(this._expressionForString("CREATE TABLE " + primaryKeyTableName + " (NAME char(40), PK long)")); + primaryKeyExpressions.addObject(this._expressionForString("ALTER TABLE " + primaryKeyTableName + " ADD PRIMARY KEY (NAME)")); + primaryKeyExpressions.addObject(this._expressionForString("CREATE UNIQUE INDEX " + primaryKeyTableName + " NAME")); + return primaryKeyExpressions.immutableClone(); + } + + public String _alterPhraseCoercingColumnsWithNames(NSArray columnNames, NSDictionary updates, NSArray entityGroup, EOSchemaGenerationOptions options) { + return this._alterPhraseInsertingColumnsWithNames(columnNames, entityGroup, options); + } + + public String _alterPhraseDeletingColumnsWithNames(NSArray columnNames, NSArray entityGroup, EOSchemaGenerationOptions options) { + StringBuffer phrase = new StringBuffer(); + int j = columnNames.count(); + for(int i = 0; i < j; i++) { + phrase.append("" + (i == 0 ? "" : this._alterPhraseJoinString()) + "remove column " + columnNames.objectAtIndex(i)); + } + return phrase.toString(); + } + + public String _alterPhraseInsertionClausePrefixAtIndex(int columnIndex) { + return "add column"; + } + + public String _alterPhraseJoinString() { + return " "; + } + + /* + * [PJYF Oct 19 2004] + * This is a bad hack to get WO to create indes for external keys. + * We use the primary key constrain generation to create our indexes. + * But we need to be carefull not to overwrite previous constrains + * + */ + protected boolean isSinglePrimaryKeyAttribute(EOAttribute attribute) { + if (attribute == null) return false; + EOEntity entity = (EOEntity)attribute.entity(); + if ( (entity == null) || entity.isAbstractEntity() || (entity.externalName() == null) ) return false; + NSArray primaryKeyAttributes = entity.primaryKeyAttributes(); + if (primaryKeyAttributes.count() != 1) return false; + return attribute.name().equals(((EOAttribute)primaryKeyAttributes.lastObject()).name()); + } + + public NSArray primaryKeyConstraintStatementsForEntityGroup(NSArray entityGroup) { + if(entityGroup == null) return NSArray.EmptyArray; + + NSMutableDictionary columnNameDictionary = new NSMutableDictionary(); + NSMutableArray primaryKeyConstraintExpressions = new NSMutableArray(); + + for (Enumeration enumerator = entityGroup.objectEnumerator(); enumerator.hasMoreElements(); ) { + EOEntity entity = (EOEntity)enumerator.nextElement(); + String tableName = entity.externalName(); + NSArray primaryKeyAttributes = entity.primaryKeyAttributes(); + boolean singlePrimaryKey = primaryKeyAttributes.count() == 1; + if( (tableName != null) && ( ! "".equals(tableName) ) && (primaryKeyAttributes.count() > 0) ) { + NSArray expressions = super.primaryKeyConstraintStatementsForEntityGroup(entityGroup); + if( (expressions != null) && (expressions.count() > 0) ) primaryKeyConstraintExpressions.addObjectsFromArray(expressions); + for (Enumeration attributeEnumerator = primaryKeyAttributes.objectEnumerator(); attributeEnumerator.hasMoreElements(); ) { + String columnName = ((EOAttribute)attributeEnumerator.nextElement()).columnName(); + columnNameDictionary.setObjectForKey(columnName, entity.externalName() + "." + columnName); + EOSQLExpression expression = this._expressionForString("create " + ( singlePrimaryKey ? "unique" : "" ) + " index " + entity.externalName() + " " + columnName); + if(expression != null) primaryKeyConstraintExpressions.addObject( expression ); + } + } + } + + for (Enumeration enumerator = entityGroup.objectEnumerator(); enumerator.hasMoreElements(); ) { + EOEntity entity = (EOEntity)enumerator.nextElement(); + String tableName = entity.externalName(); + if( (tableName != null) && ( ! "".equals(tableName) ) ) { + for (Enumeration relationshipEnumerator = entity.relationships().objectEnumerator(); relationshipEnumerator.hasMoreElements(); ) { + EORelationship relationship = (EORelationship)relationshipEnumerator.nextElement(); + if( ! relationship.isFlattened() ) { + NSArray destinationAttributes = relationship.destinationAttributes(); + + // First exclude all the destination entity primary keys + for (Enumeration attributeEnumerator = relationship.destinationEntity().primaryKeyAttributes().objectEnumerator(); attributeEnumerator.hasMoreElements(); ) { + EOAttribute attribute = (EOAttribute)attributeEnumerator.nextElement(); + columnNameDictionary.setObjectForKey(attribute.columnName(), relationship.destinationEntity().externalName() + "." + attribute.columnName()); + } + // Then deal with our end of things + for (Enumeration attributeEnumerator = relationship.sourceAttributes().objectEnumerator(); attributeEnumerator.hasMoreElements(); ) { + EOAttribute attribute = (EOAttribute)attributeEnumerator.nextElement(); + if( (! this.isSinglePrimaryKeyAttribute(attribute)) && (columnNameDictionary.objectForKey(tableName + "." + attribute.columnName()) != null) ) { + columnNameDictionary.setObjectForKey(attribute.columnName(), tableName + "." + attribute.columnName()); + EOSQLExpression expression = this._expressionForString("create index " + tableName + " " + attribute.columnName()); + if(expression != null) primaryKeyConstraintExpressions.addObject( expression ); + } + } + // Then deal with the other side + if(entity.model() == relationship.destinationEntity().model()) { + for (Enumeration attributeEnumerator = relationship.destinationAttributes().objectEnumerator(); attributeEnumerator.hasMoreElements(); ) { + EOAttribute attribute = (EOAttribute)attributeEnumerator.nextElement(); + String destinationTableName = relationship.destinationEntity().externalName(); + if( (destinationTableName != null) && ( ! "".equals(destinationTableName) ) ) { + if( (! this.isSinglePrimaryKeyAttribute(attribute)) && (columnNameDictionary.objectForKey(destinationTableName + "." + attribute.columnName()) != null) ) { + columnNameDictionary.setObjectForKey(attribute.columnName(), destinationTableName + "." + attribute.columnName()); + EOSQLExpression expression = this._expressionForString("create index " + destinationTableName + " " + attribute.columnName()); + if(expression != null) primaryKeyConstraintExpressions.addObject( expression ); + } + if( (! relationship.isCompound() ) && (relationship.sourceAttributes().count() == 1) && (relationship.destinationAttributes().count() == 1) ) { + String semantics; + switch(relationship.joinSemantic()) { + case EORelationship.FullOuterJoin: // '\001' + case EORelationship.LeftOuterJoin: // '\002' + case EORelationship.RightOuterJoin: // '\003' + semantics = "*"; + break; + + default: + semantics = "="; + break; + } + String sourceColumn = ((EOAttribute)relationship.sourceAttributes().objectAtIndex(0)).columnName(); + String destinationColumn = ((EOAttribute)relationship.destinationAttributes().objectAtIndex(0)).columnName(); + EOSQLExpression expression = this._expressionForString("delete from _SYS_RELATIONSHIP where relationshipName = '" + relationship.name() + "' and source_table = '" + tableName + "' "); + if(expression != null) primaryKeyConstraintExpressions.addObject( expression ); + expression = this._expressionForString("insert into _SYS_RELATIONSHIP (relationshipName, source_table, source_column, dest_table, dest_column, operator, one_to_many) values ('" + relationship.name() + "','" + tableName + "','" + sourceColumn + "','" + destinationTableName + "','" + destinationColumn + "','" + semantics + "'," + (relationship.isToMany() ? 1 : 0) + ")"); + if(expression != null) primaryKeyConstraintExpressions.addObject( expression ); + } + } + } + } + } + } + } + } + return primaryKeyConstraintExpressions.immutableClone(); + } + + public boolean isColumnTypeEquivalentToColumnType(EOSchemaSynchronization.ColumnTypes candidate, EOSchemaSynchronization.ColumnTypes columnType, EOSchemaGenerationOptions options) { + return candidate.name().equals(columnType.name()) && ( candidate.width() == columnType.width() ); + } + + public NSArray statementsToDropForeignKeyConstraintsOnEntityGroups(NSArray entityGroups, NSDictionary changes, NSDictionary options) { + return NSArray.EmptyArray; + } + + public NSArray statementsToDropPrimaryKeyConstraintsOnEntityGroups(NSArray entityGroups, EOSchemaSynchronizationModelChanges changes, EOSchemaGenerationOptions options) { + if(entityGroups == null) return NSArray.EmptyArray; + if(changes == null) changes = newChanges(); + + NSMutableArray expressions = new NSMutableArray(); + for (Enumeration enumerator = entityGroups.objectEnumerator(); enumerator.hasMoreElements(); ) { + NSArray entities = (NSArray)enumerator.nextElement(); + EOEntity _last = (EOEntity)entities.lastObject(); //only need entity to get the table name for the group + String nameInObjectStore = _nameInObjectStoreForEntityGroupWithChangeDictionary(entities, changes.changesForTableNamed(_last.externalName())); + if ( (nameInObjectStore != null) && ( ! "".equals(nameInObjectStore) ) ) { + expressions.addObject(this._expressionForString("delete from _SYS_RELATIONSHIP where source_table = '" + nameInObjectStore + "' or dest_table = '" + nameInObjectStore + "'")); + } + } + return expressions.immutableClone(); + } + + public NSArray statementsToImplementPrimaryKeyConstraintsOnEntityGroups(NSArray entityGroups, EOSchemaSynchronizationModelChanges changes, EOSchemaGenerationOptions options) { + NSArray primaryKeyExpressions = this.primaryKeyConstraintStatementsForEntityGroups(entityGroups); + NSMutableArray createStatements = new NSMutableArray(); + NSMutableArray otherStatements = new NSMutableArray(); + for (Enumeration enumerator = primaryKeyExpressions.objectEnumerator(); enumerator.hasMoreElements(); ) { + EOSQLExpression expression = (EOSQLExpression)enumerator.nextElement(); + String statement = expression.statement(); + if(statement.startsWith("create")) { + createStatements.addObject(expression); + } else if( ! statement.startsWith("delete from _SYS_RELATIONSHIP") ) { + otherStatements.addObject(expression); + } + } + return createStatements.arrayByAddingObjectsFromArray(otherStatements); + } + + public NSArray statementsToModifyColumnNullRule(String columnName, String tableName, boolean allowsNull, EOSchemaGenerationOptions options) { + return new NSArray(this._expressionForString("alter table " + tableName + " add column " + columnName + " set " + (allowsNull ? "null" : "not null"))); + } + + public NSArray statementsToRenameColumnNamed(String columnName, String tableName, String newName, EOSchemaGenerationOptions options) { + return new NSArray(this._expressionForString("alter table " + tableName + " rename " + columnName + " to " + newName)); + } + + public NSArray statementsToRenameTableNamed(String tableName, String newName, EOSchemaGenerationOptions options) { + return new NSArray(this._expressionForString("rename " + tableName + " " + newName)); + } + + public boolean supportsDirectColumnCoercion() { + return true; + } + + public boolean supportsDirectColumnDeletion() { + return true; + } + + public boolean supportsDirectColumnInsertion() { + return true; + } + + public boolean supportsDirectColumnNullRuleModification() { + return true; + } + + public boolean supportsDirectColumnRenaming() { + return true; + } + + public boolean supportsSchemaSynchronization() { + return true; + } + + public NSArray primaryKeySupportStatementsForEntityGroup(NSArray entityGroup) { + return NSArray.EmptyArray; + } + + public NSArray dropPrimaryKeySupportStatementsForEntityGroup(NSArray entityGroup) { + return NSArray.EmptyArray; + } + + public EOSchemaSynchronizationColumnChanges objectStoreChangesFromAttributeToAttribute(EOAttribute schemaAttribute, EOAttribute modelAttribute) { + EOSchemaSynchronizationColumnChanges objectStoreChanges = super.objectStoreChangesFromAttributeToAttribute(schemaAttribute, modelAttribute); + if(objectStoreChanges.valueForKey("precision") != null || objectStoreChanges.valueForKey("scale") != null) { + objectStoreChanges.clearPrecision(); + objectStoreChanges.clearScale(); + } + if( ! modelAttribute.externalType().equals(schemaAttribute.externalType()) ) { + if(modelAttribute.externalType().equals("varchar") && schemaAttribute.externalType().equals("char")) + objectStoreChanges.clearExternalType(); + } else { + if(schemaAttribute.externalType().equals("object") && objectStoreChanges.valueForKey("width") != null) + objectStoreChanges.clearWidth(); + } + if((modelAttribute.externalType().equals("char") || modelAttribute.externalType().equals("varchar")) && modelAttribute.width() == 1024 && schemaAttribute.width() == 1023) + objectStoreChanges.clearWidth(); + + return objectStoreChanges; + } + + public String schemaCreationScriptForEntities(NSArray arg0, NSDictionary arg1) { + System.err.println("calling OpenBaseSynchronizationFactory.schemaCreationScriptForEntities"); + return null; + } + + public NSArray schemaCreationStatementsForEntities(NSArray arg0, NSDictionary arg1) { + System.err.println("calling OpenBaseSynchronizationFactory.schemaCreationStatementsForEntities"); + return null; + } + } + + public _OpenBasePlugIn(JDBCAdaptor adaptor) { + super(adaptor); + } + + public String connectionURL() { + return super.connectionURL() + ":wo"; + } + + public String defaultDriverName() { + return DriverClassName; + } + + public String databaseProductName() { + return DriverProductName; + } + + public Class defaultExpressionClass() { + return _OpenBasePlugIn.OpenBaseExpression.class; + } + + public EOSchemaSynchronizationFactory createSchemaSynchronizationFactory() { + return new OpenBaseSynchronizationFactory(this.adaptor()); + } + + public boolean isPseudoColumnName(String columnName) { + return columnName.equalsIgnoreCase("_timestamp") || columnName.equalsIgnoreCase("_version") || super.isPseudoColumnName(columnName); + } + + public NSDictionary jdbcInfo() { + NSDictionary jdbcInfo = super.jdbcInfo(); + JDBCContext jdbccontext = this.adaptor()._cachedAdaptorContext(); + try { + jdbccontext.connection().commit(); + } catch(SQLException exception) { + if(NSLog.debugLoggingAllowedForLevelAndGroups(3, 0x0L)) NSLog.debug.appendln(exception); + } + return jdbcInfo; + } + + private static final String DriverClassName = "com.openbase.jdbc.ObDriver"; + private static final String DriverProductName = "OpenBase"; +} diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.properties b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.properties new file mode 100644 index 00000000000..476057a2a59 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.properties @@ -0,0 +1,10 @@ +classes.dir = bin +project.name=OpenBaseWOPKPlugIn +project.name.lowercase=openbasewopkplugin +principalClass = +customInfoPListContent = +eoAdaptorClassName = +cfBundleVersion = +cfBundleShortVersion = +cfBundleID = org.mywoapp +javaVersion = 1.5+ diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.xml b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.xml new file mode 100644 index 00000000000..03c57bb9c81 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/build.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.exclude.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.exclude.patternset new file mode 100644 index 00000000000..56fb545fa67 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.exclude.patternset @@ -0,0 +1 @@ +build.properties diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.include.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.include.patternset new file mode 100644 index 00000000000..3179091db39 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/classes.include.patternset @@ -0,0 +1,2 @@ +**/*.class +*.properties diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.exclude.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.exclude.patternset new file mode 100644 index 00000000000..905050dfb73 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.exclude.patternset @@ -0,0 +1,3 @@ +**/*.eomodeld~/ +**/*.woa/** +**/*.framework/** diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.include.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.include.patternset new file mode 100644 index 00000000000..611978755e2 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/resources.include.patternset @@ -0,0 +1,3 @@ +Components/**/*.wo/**/* +Components/**/*.api +Resources/**/* \ No newline at end of file diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.exclude.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.exclude.patternset new file mode 100644 index 00000000000..9435a512320 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.exclude.patternset @@ -0,0 +1,3 @@ +**/*.woa/** +**/*.framework/** +**/*.eomodeld~/** diff --git a/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.include.patternset b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.include.patternset new file mode 100644 index 00000000000..234cdc88bb7 --- /dev/null +++ b/Frameworks/PlugIns/OpenBaseWOPKPlugIn/woproject/wsresources.include.patternset @@ -0,0 +1 @@ +WebServerResources/**/*