// [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 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());
 }
Exemple #3
0
  /**
   * Overrides the parent implementation to provide a more efficient mechanism for generating
   * primary keys, while generating the primary key support on the fly.
   *
   * @param count the batch size
   * @param entity the entity requesting primary keys
   * @param channel open JDBCChannel
   * @return NSArray of NSDictionary where each dictionary corresponds to a unique primary key value
   */
  public NSArray newPrimaryKeys(int count, EOEntity entity, JDBCChannel channel) {
    if (isPrimaryKeyGenerationNotSupported(entity)) {
      return null;
    }

    EOAttribute attribute = (EOAttribute) entity.primaryKeyAttributes().lastObject();
    String attrName = attribute.name();
    boolean isIntType = "i".equals(attribute.valueType());

    NSMutableArray results = new NSMutableArray(count);
    String sequenceName = sequenceNameForEntity(entity);
    DB2Expression expression = new DB2Expression(entity);

    boolean succeeded = false;
    for (int tries = 0; !succeeded && tries < 2; tries++) {
      while (results.count() < count) {
        try {
          StringBuffer sql = new StringBuffer();
          sql.append("SELECT ");
          sql.append("next value for " + sequenceName + " AS KEY");
          sql.append(" from sysibm.sysdummy1");
          expression.setStatement(sql.toString());
          channel.evaluateExpression(expression);
          try {
            NSDictionary row;
            while ((row = channel.fetchRow()) != null) {
              Enumeration pksEnum = row.allValues().objectEnumerator();
              while (pksEnum.hasMoreElements()) {
                Number pkObj = (Number) pksEnum.nextElement();
                Number pk;
                if (isIntType) {
                  pk = Integer.valueOf(pkObj.intValue());
                } else {
                  pk = Long.valueOf(pkObj.longValue());
                }
                results.addObject(new NSDictionary(pk, attrName));
              }
            }
          } finally {
            channel.cancelFetch();
          }
          succeeded = true;
        } catch (JDBCAdaptorException ex) {
          throw ex;
        }
      }
    }

    if (results.count() != count) {
      throw new IllegalStateException(
          "Unable to generate primary keys from the sequence for " + entity + ".");
    }

    return results;
  }
 // [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
       });
 }
Exemple #5
0
 // Shameless stolen from PostresqlSynchronizationFactory - davidleber
 //
 // I blame statementstToConvertColumnType for not taking a damn EOAttribute for
 // having to steal this from EOSQLExpression
 public String columnTypeStringForAttribute(EOAttribute attribute) {
   if (attribute.precision() != 0) {
     String precision = String.valueOf(attribute.precision());
     String scale = String.valueOf(attribute.scale());
     return _NSStringUtilities.concat(attribute.externalType(), "(", precision, ",", scale, ")");
   }
   if (attribute.width() != 0) {
     String width = String.valueOf(attribute.width());
     return _NSStringUtilities.concat(attribute.externalType(), "(", width, ")");
   }
   return attribute.externalType();
 }
 /**
  * Generates an NSDictionary representing primary key values, both simple and compound. If values
  * are encrypted we try to create the correct attribute value type. Supported types are: strings,
  * numbers, timestamps and custom attributes with a factory method using a string argument.
  *
  * @param value the primary key value, either a single value or a collection
  * @param entity the entity used to gather primary key information
  * @param isEncrypted yes/no
  * @return a dictionary with primary key values
  */
 private static NSDictionary processPrimaryKeyValue(
     String value, EOEntity entity, boolean isEncrypted) {
   NSArray pkAttributeNames = entity.primaryKeyAttributeNames();
   try {
     pkAttributeNames =
         pkAttributeNames.sortedArrayUsingComparator(NSComparator.AscendingStringComparator);
   } catch (NSComparator.ComparisonException ex) {
     log.error("Unable to sort attribute names: " + ex);
     throw new NSForwardException(ex);
   }
   NSArray values =
       isEncrypted
           ? NSArray.componentsSeparatedByString(
               ERXCrypto.blowfishDecode(value).trim(), AttributeValueSeparator)
           : NSArray.componentsSeparatedByString(value, AttributeValueSeparator);
   int attrCount = pkAttributeNames.count();
   NSMutableDictionary result = new NSMutableDictionary(attrCount);
   for (int i = 0; i < attrCount; i++) {
     String currentAttributeName = (String) pkAttributeNames.objectAtIndex(i);
     EOAttribute currentAttribute = entity.attributeNamed(currentAttributeName);
     Object currentValue = values.objectAtIndex(i);
     switch (currentAttribute.adaptorValueType()) {
       case 3:
         NSTimestampFormatter tsf = new NSTimestampFormatter();
         try {
           currentValue = tsf.parseObject((String) currentValue);
         } catch (java.text.ParseException ex) {
           log.error("Error while trying to parse: " + currentValue);
           throw new NSForwardException(ex);
         }
       case 1:
         if (currentAttribute.valueFactoryMethodName() != null) {
           currentValue = currentAttribute.newValueForString((String) currentValue);
         }
       case 0:
         currentValue = new java.math.BigDecimal((String) currentValue);
     }
     result.setObjectForKey(currentValue, currentAttributeName);
   }
   return result;
 }
Exemple #7
0
 @Override
 public NSArray<EOSQLExpression> statementsToRenameColumnNamed(
     String columnName, String tableName, String newName, EOSchemaGenerationOptions options) {
   EOAttribute attribute =
       attributeInEntityWithColumnName(entityForTableName(tableName), newName);
   String nullStatement = attribute.allowsNull() ? " NULL" : " NOT NULL";
   String externalType = columnTypeStringForAttribute(attribute);
   return new NSArray<EOSQLExpression>(
       _expressionForString(
           (new StringBuilder())
               .append("ALTER TABLE ")
               .append(formatTableName(tableName))
               .append(" CHANGE ")
               .append(formatColumnName(columnName))
               .append(" ")
               .append(formatColumnName(newName))
               .append(" ")
               .append(externalType)
               .append(nullStatement)
               .toString()));
 }
Exemple #8
0
 @Override
 public NSArray<EOSQLExpression> statementsToInsertColumnForAttribute(
     EOAttribute attribute, EOSchemaGenerationOptions options) {
   String columnCreationClause = _columnCreationClauseForAttribute(attribute);
   return new NSArray<EOSQLExpression>(
       _expressionForString(
           (new StringBuilder())
               .append("ALTER TABLE ")
               .append(attribute.entity().externalName())
               .append(_alterPhraseInsertionClausePrefixAtIndex(0))
               .append(columnCreationClause)
               .toString()));
 }
    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 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();
    }
 // [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());
 }
 private AttributeRetriever(EOAttribute attribute) {
   this.propertyName = attribute.name();
   this.attribute = attribute;
 }
  /**
   * Returns an EOAttribute with all of its fields filled in based on the properties of this
   * ERXMigrationColumn. The attribute is attached to the given entity.
   *
   * @param entity the entity to add the attribute to
   * @return an EOAttribute with all of its fields filled in
   */
  @SuppressWarnings("unchecked")
  public EOAttribute _newAttribute(EOEntity entity) {
    EOAdaptor eoAdaptor = _table.database().adaptor();
    // MS: Hack to make Memory adaptor migrations "work"
    if (!(eoAdaptor instanceof JDBCAdaptor)) {
      EOAttribute nonJdbcAttribute = new EOAttribute();
      nonJdbcAttribute.setName(_name);
      nonJdbcAttribute.setColumnName(_name);
      nonJdbcAttribute.setExternalType("nonJdbcAttribute");
      entity.addAttribute(nonJdbcAttribute);
      return nonJdbcAttribute;
    }

    JDBCAdaptor adaptor = (JDBCAdaptor) _table.database().adaptor();
    ERXSQLHelper sqlHelper = ERXSQLHelper.newSQLHelper(adaptor);
    String externalType = sqlHelper.externalTypeForJDBCType(adaptor, _jdbcType);
    if (externalType == null) {
      externalType = "IF_YOU_ARE_SEEING_THIS_SOMETHING_WENT_WRONG_WITH_EXTERNAL_TYPES";
    }
    EOAttribute attribute =
        adaptor.createAttribute(
            _name, _name, _jdbcType, externalType, _precision, _scale, _allowsNull ? 1 : 0);
    if (_width > 0) {
      attribute.setWidth(_width);
    }
    if (_defaultValue != null) {
      NSDictionary userInfo = attribute.userInfo();
      NSMutableDictionary mutableUserInfo;
      if (userInfo == null) {
        mutableUserInfo = new NSMutableDictionary();
      } else {
        mutableUserInfo = userInfo.mutableClone();
      }
      mutableUserInfo.setObjectForKey(_defaultValue, "default");
      attribute.setUserInfo(mutableUserInfo);
    }

    if (_overrideValueType != null) {
      if (ERXMigrationColumn.NULL_VALUE_TYPE.equals(_overrideValueType)) {
        attribute.setValueType(null);
      } else {
        attribute.setValueType(_overrideValueType);
      }
      if (sqlHelper.reassignExternalTypeForValueTypeOverride(attribute)) {
        adaptor.assignExternalTypeForAttribute(attribute);
      }
    }

    if (_overrideExternalType != null) {
      attribute.setExternalType(_overrideExternalType);
    }

    entity.addAttribute(attribute);
    return attribute;
  }
    @Override
    @SuppressWarnings("unchecked")
    public String sqlStringForSQLExpression(EOQualifier eoqualifier, EOSQLExpression e) {
      ERXToManyQualifier qualifier = (ERXToManyQualifier) eoqualifier;
      StringBuilder result = new StringBuilder();
      EOEntity targetEntity = e.entity();

      NSArray<String> toManyKeys = NSArray.componentsSeparatedByString(qualifier.key(), ".");
      EORelationship targetRelationship = null;
      for (int i = 0; i < toManyKeys.count() - 1; i++) {
        targetRelationship = targetEntity.anyRelationshipNamed(toManyKeys.objectAtIndex(i));
        targetEntity = targetRelationship.destinationEntity();
      }
      targetRelationship = targetEntity.relationshipNamed(toManyKeys.lastObject());
      targetEntity = targetRelationship.destinationEntity();

      if (targetRelationship.joins() == null || targetRelationship.joins().isEmpty()) {
        // we have a flattened many to many
        String definitionKeyPath = targetRelationship.definition();
        NSArray<String> definitionKeys =
            NSArray.componentsSeparatedByString(definitionKeyPath, ".");
        EOEntity lastStopEntity = targetRelationship.entity();
        EORelationship firstHopRelationship =
            lastStopEntity.relationshipNamed(definitionKeys.objectAtIndex(0));
        EOEntity endOfFirstHopEntity = firstHopRelationship.destinationEntity();
        EOJoin join = firstHopRelationship.joins().objectAtIndex(0); // assumes 1 join
        EOAttribute sourceAttribute = join.sourceAttribute();
        EOAttribute targetAttribute = join.destinationAttribute();
        EORelationship secondHopRelationship =
            endOfFirstHopEntity.relationshipNamed(definitionKeys.objectAtIndex(1));
        join = secondHopRelationship.joins().objectAtIndex(0); // assumes 1 join
        EOAttribute secondHopSourceAttribute = join.sourceAttribute();

        NSMutableArray<String> lastStopPKeyPath = toManyKeys.mutableClone();
        lastStopPKeyPath.removeLastObject();
        lastStopPKeyPath.addObject(firstHopRelationship.name());
        lastStopPKeyPath.addObject(targetAttribute.name());
        String firstHopRelationshipKeyPath = lastStopPKeyPath.componentsJoinedByString(".");
        result.append(e.sqlStringForAttributeNamed(firstHopRelationshipKeyPath));
        result.append(" IN ( SELECT ");

        result.append(lastStopEntity.externalName());
        result.append('.');
        result.append(lastStopEntity.primaryKeyAttributes().objectAtIndex(0).columnName());

        result.append(" FROM ");

        result.append(lastStopEntity.externalName());
        result.append(',');

        lastStopPKeyPath.removeLastObject();
        String tableAliasForJoinTable =
            (String)
                e.aliasesByRelationshipPath()
                    .objectForKey(
                        lastStopPKeyPath.componentsJoinedByString(".")); // "j"; //+random#
        result.append(endOfFirstHopEntity.externalName());
        result.append(' ');
        result.append(tableAliasForJoinTable);

        result.append(" WHERE ");

        appendColumnForAttributeToStringBuilder(sourceAttribute, result);
        result.append('=');
        result.append(e.sqlStringForAttributeNamed(firstHopRelationshipKeyPath));

        if (qualifier.elements() != null) {
          NSArray pKeys = ERXEOAccessUtilities.primaryKeysForObjects(qualifier.elements());
          result.append(" AND ");

          result.append(tableAliasForJoinTable);
          result.append('.');
          result.append(secondHopSourceAttribute.columnName());

          result.append(" IN (");
          EOAttribute pk = targetEntity.primaryKeyAttributes().lastObject();
          for (int i = 0; i < pKeys.count(); i++) {

            Object key = pKeys.objectAtIndex(i);
            String keyString = e.formatValueForAttribute(key, pk);
            // AK: default is is broken
            if ("NULL".equals(keyString)) {
              keyString = "" + key;
            }
            result.append(keyString);
            if (i < pKeys.count() - 1) {
              result.append(',');
            }
          }
          result.append(") ");
        }
        result.append(" GROUP BY ");
        appendColumnForAttributeToStringBuilder(sourceAttribute, result);

        result.append(" HAVING COUNT(*)");
        if (qualifier.minCount() <= 0) {
          result.append("=" + qualifier.elements().count());
        } else {
          result.append(">=" + qualifier.minCount());
        }
        result.append(" )");
      } else {
        throw new RuntimeException("not implemented!!");
      }
      return result.toString();
    }
 protected static void appendColumnForAttributeToStringBuilder(
     EOAttribute attribute, StringBuilder sb) {
   sb.append(attribute.entity().externalName());
   sb.append('.');
   sb.append(attribute.columnName());
 }