예제 #1
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;
  }
  // ENHANCEME: Could also place a sha hash of the blowfish key in the form values so we can know if
  // we are using
  //		  the correct key for decryption.
  public static String encodeEnterpriseObjectsPrimaryKeyForUrl(
      NSArray eos, String separator, boolean encrypt) {
    // Array of objects to be encoded
    NSMutableArray encoded = new NSMutableArray();

    // If the separator is not specified, default to the one given at class init
    if (separator == null) separator = entityNameSeparator();

    // Add the separator if needed
    if (isSpecifySeparatorInURL()) encoded.addObject("sep=" + separator);

    int c = 1;
    // Iterate through the objects
    for (Enumeration e = eos.objectEnumerator(); e.hasMoreElements(); ) {
      EOEnterpriseObject eo = (EOEnterpriseObject) e.nextElement();

      // Get the primary key of the object
      NSArray pkValues = ERXEOControlUtilities.primaryKeyArrayForObject(eo);
      if (pkValues == null && eo instanceof ERXGeneratesPrimaryKeyInterface) {
        NSDictionary pkDict = ((ERXGeneratesPrimaryKeyInterface) eo).primaryKeyDictionary(false);
        if (pkDict != null) pkValues = pkDict.allValues();
      }
      if (pkValues == null) throw new RuntimeException("Primary key is null for object: " + eo);
      String pk = pkValues.componentsJoinedByString(AttributeValueSeparator);

      // Get the EncodedEntityName of the object
      String encodedEntityName = entityNameEncode(eo);

      // Add the result to the list of encoded objects
      encoded.addObject(
          encodedEntityName
              + separator
              + (encrypt ? "E" : "")
              + c++
              + "="
              + (encrypt ? ERXCrypto.blowfishEncode(pk) : pk));
    }

    // Return the result as an url-encoded string
    return encoded.componentsJoinedByString("&");
  }