Beispiel #1
0
  @Override
  public final String formatJSON() {
    List<Map<String, String>> f = new ArrayList<Map<String, String>>();
    List<List<Object>> r = new ArrayList<List<Object>>();

    Map<String, String> fieldMap;
    for (Field<?> field : fields) {
      fieldMap = new LinkedHashMap<String, String>();
      fieldMap.put("name", field.getName());
      fieldMap.put("type", field.getDataType().getTypeName().toUpperCase());

      f.add(fieldMap);
    }

    for (Record record : this) {
      List<Object> list = new ArrayList<Object>();

      for (int index = 0; index < fields.fields.length; index++) {
        list.add(record.getValue(index));
      }

      r.add(list);
    }

    Map<String, List<?>> map = new LinkedHashMap<String, List<?>>();

    map.put("fields", f);
    map.put("records", r);

    return JSONObject.toJSONString(map);
  }
Beispiel #2
0
  /**
   * Get the returning record in those dialects that do not support fetching arbitrary fields from
   * JDBC's {@link Statement#getGeneratedKeys()} method.
   */
  @SuppressWarnings("unchecked")
  private final void selectReturning(Configuration configuration, Object... values) {
    if (values != null && values.length > 0) {

      // This shouldn't be null, as relevant dialects should
      // return empty generated keys ResultSet
      if (into.getIdentity() != null) {
        Field<Number> field = (Field<Number>) into.getIdentity().getField();
        Number[] ids = new Number[values.length];
        for (int i = 0; i < values.length; i++) {
          ids[i] = field.getDataType().convert(values[i]);
        }

        // Only the IDENTITY value was requested. No need for an
        // additional query
        if (returning.size() == 1 && new Fields(returning).field(field) != null) {
          for (Number id : ids) {
            R typed = Utils.newRecord(into, configuration);
            ((AbstractRecord) typed).setValue(field, new Value<Number>(id));
            getReturnedRecords().add(typed);
          }
        }

        // Other values are requested, too. Run another query
        else {
          returned =
              create(configuration)
                  .select(returning)
                  .from(into)
                  .where(field.in(ids))
                  .fetchInto(into);
        }
      }
    }
  }
Beispiel #3
0
  Expression(ExpressionOperator operator, Field<T> lhs, Field<?>... rhs) {
    super(operator.toSQL(), lhs.getDataType(), Util.combine(lhs, rhs));

    this.operator = operator;
    this.lhs = lhs;
    this.rhs = new FieldList();
    this.rhs.addAll(Arrays.asList(rhs));
  }
Beispiel #4
0
  @SuppressWarnings({"unchecked"})
  ArrayTable(Field<?> array, String alias) {
    super(alias);

    Class<?> arrayType;

    // TODO [#523] Solve this in a more object-oriented way...
    if (array.getDataType().getType().isArray()) {
      arrayType = array.getDataType().getType().getComponentType();
    }

    // [#1110] Keep track of element type information of Oracle VARRAY / TABLE types
    else if (array instanceof ArrayConstant) {
      arrayType = array.getDataType().getType();
    }

    // [#1111] Keep track of element type information of Oracle
    // VARRAY / TABLE types returned from functions
    else if (ArrayRecord.class.isAssignableFrom(array.getDataType().getType())) {
      // TODO [#523] This information should be available in ARRAY meta-data
      ArrayRecord<?> dummy =
          Utils.newArrayRecord(
              (Class<ArrayRecord<?>>) array.getDataType().getType(), new DefaultConfiguration());
      arrayType = dummy.getDataType().getType();
    }

    // Is this case possible?
    else {
      arrayType = Object.class;
    }

    this.array = array;
    this.alias = alias;
    this.field = init(alias, arrayType);

    init(alias, arrayType);
  }
Beispiel #5
0
  @Override
  public final String formatXML() {
    final int size = getFields().size();

    StringBuilder sb = new StringBuilder();

    sb.append("<result xmlns=\"http://www.jooq.org/xsd/jooq-export-2.6.0.xsd\">");
    sb.append("<fields>");

    for (Field<?> field : getFields()) {
      sb.append("<field name=\"");
      sb.append(escapeXML(field.getName()));
      sb.append("\" ");
      sb.append("type=\"");
      sb.append(field.getDataType().getTypeName().toUpperCase());
      sb.append("\"/>");
    }

    sb.append("</fields>");
    sb.append("<records>");

    for (Record record : this) {
      sb.append("<record>");

      for (int index = 0; index < size; index++) {
        Field<?> field = getField(index);
        Object value = record.getValue(index);

        sb.append("<value field=\"");
        sb.append(escapeXML(field.getName()));
        sb.append("\"");

        if (value == null) {
          sb.append("/>");
        } else {
          sb.append(">");
          sb.append(escapeXML(format0(value)));
          sb.append("</value>");
        }
      }

      sb.append("</record>");
    }

    sb.append("</records>");
    sb.append("</result>");

    return sb.toString();
  }
Beispiel #6
0
  @Override
  public final Document intoXML() {
    final int size = getFields().size();

    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document document = builder.newDocument();

      Element eResult = document.createElement("result");
      eResult.setAttribute("xmlns", "http://www.jooq.org/xsd/jooq-export-2.6.0.xsd");
      document.appendChild(eResult);

      Element eFields = document.createElement("fields");
      eResult.appendChild(eFields);

      for (Field<?> field : getFields()) {
        Element eField = document.createElement("field");
        eField.setAttribute("name", field.getName());
        eField.setAttribute("type", field.getDataType().getTypeName().toUpperCase());
        eFields.appendChild(eField);
      }

      Element eRecords = document.createElement("records");
      eResult.appendChild(eRecords);

      for (Record record : this) {
        Element eRecord = document.createElement("record");
        eRecords.appendChild(eRecord);

        for (int index = 0; index < size; index++) {
          Field<?> field = getField(index);
          Object value = record.getValue(index);

          Element eValue = document.createElement("value");
          eValue.setAttribute("field", field.getName());
          eRecord.appendChild(eValue);

          if (value != null) {
            eValue.setTextContent(format0(value));
          }
        }
      }

      return document;
    } catch (ParserConfigurationException ignore) {
      throw new RuntimeException(ignore);
    }
  }
Beispiel #7
0
  private final Table<Record> table(Configuration configuration) {
    switch (configuration.getDialect()) {
      case ORACLE:
        {
          if (array.getDataType().getType().isArray()) {
            return simulate().as(alias);
          } else {
            return new OracleArrayTable().as(alias);
          }
        }

      case H2:
        {
          return new H2ArrayTable().as(alias);
        }

        // [#756] These dialects need special care when aliasing unnested
        // arrays
      case HSQLDB:
      case POSTGRES:
        {
          return new PostgresHSQLDBTable().as(alias);
        }

        // Other dialects can simulate unnested arrays using UNION ALL
      default:
        {
          if (array.getDataType().getType().isArray() && array instanceof Param) {
            return simulate();
          } else {
            throw new SQLDialectNotSupportedException(
                "ARRAY TABLE is not supported for " + configuration.getDialect());
          }
        }
    }
  }
Beispiel #8
0
    @Override
    public R operate(R target) throws MappingException {
      AbstractRecord source = AbstractRecord.this;

      try {

        // [#1522] [#2989] If possible the complete state of this record should be copied onto the
        // other record
        if (target instanceof AbstractRecord) {
          AbstractRecord t = (AbstractRecord) target;

          // Iterate over target fields, to avoid ambiguities when two source fields share the same
          // name.
          for (int targetIndex = 0; targetIndex < t.size(); targetIndex++) {
            Field<?> targetField = t.field(targetIndex);
            int sourceIndex = fields.indexOf(targetField);

            if (sourceIndex >= 0) {
              DataType<?> targetType = targetField.getDataType();
              Value<?> sourceValue = values[sourceIndex];

              t.values[targetIndex] =
                  new Value<Object>(
                      targetType.convert(sourceValue.getValue()),
                      targetType.convert(sourceValue.getOriginal()),
                      sourceValue.isChanged());
            }
          }
        } else {
          for (Field<?> targetField : target.fields()) {
            Field<?> sourceField = field(targetField);

            if (sourceField != null) {
              Utils.setValue(target, targetField, source, sourceField);
            }
          }
        }

        return target;
      }

      // All reflection exceptions are intercepted
      catch (Exception e) {
        throw new MappingException("An error ocurred when mapping record to " + target, e);
      }
    }
Beispiel #9
0
  private static final Fields init(String alias, Class<?> arrayType) {
    List<Field<?>> result = new ArrayList<Field<?>>();

    // [#1114] VARRAY/TABLE of OBJECT have more than one field
    if (UDTRecord.class.isAssignableFrom(arrayType)) {
      try {
        UDTRecord<?> record = (UDTRecord<?>) arrayType.newInstance();
        for (Field<?> f : record.fields()) {
          result.add(fieldByName(f.getDataType(), alias, f.getName()));
        }
      } catch (Exception e) {
        throw new DataTypeException("Bad UDT Type : " + arrayType, e);
      }
    }

    // Simple array types have a synthetic field called "COLUMN_VALUE"
    else {
      result.add(fieldByName(Factory.getDataType(arrayType), alias, "COLUMN_VALUE"));
    }

    return new Fields(result);
  }
Beispiel #10
0
 @Override
 public final <T> AggregateFilterStep<T> withinGroupOrderBy(Field<T> field) {
   return new Function<T>("mode", field.getDataType()).withinGroupOrderBy(field);
 }
Beispiel #11
0
  public static <T> void writeToSQLOutput(SQLOutput stream, Field<T> field, T value)
      throws SQLException {
    Class<? extends T> type = field.getType();

    writeToSQLOutput(stream, type, field.getDataType(), value);
  }
Beispiel #12
0
  @SuppressWarnings("unchecked")
  public static <T> T getFromSQLInput(Configuration configuration, SQLInput stream, Field<T> field)
      throws SQLException {
    Class<? extends T> type = field.getType();
    DataType<T> dataType = field.getDataType();

    if (type == Blob.class) {
      return (T) stream.readBlob();
    } else if (type == Boolean.class) {
      return (T) checkWasNull(stream, Boolean.valueOf(stream.readBoolean()));
    } else if (type == BigInteger.class) {
      BigDecimal result = stream.readBigDecimal();
      return (T) (result == null ? null : result.toBigInteger());
    } else if (type == BigDecimal.class) {
      return (T) stream.readBigDecimal();
    } else if (type == Byte.class) {
      return (T) checkWasNull(stream, Byte.valueOf(stream.readByte()));
    } else if (type == byte[].class) {

      // [#1327] Oracle cannot deserialise BLOBs as byte[] from SQLInput
      if (dataType.isLob()) {
        Blob blob = null;
        try {
          blob = stream.readBlob();
          return (T) (blob == null ? null : blob.getBytes(1, (int) blob.length()));
        } finally {
          Util.safeFree(blob);
        }
      } else {
        return (T) stream.readBytes();
      }
    } else if (type == Clob.class) {
      return (T) stream.readClob();
    } else if (type == Date.class) {
      return (T) stream.readDate();
    } else if (type == Double.class) {
      return (T) checkWasNull(stream, Double.valueOf(stream.readDouble()));
    } else if (type == Float.class) {
      return (T) checkWasNull(stream, Float.valueOf(stream.readFloat()));
    } else if (type == Integer.class) {
      return (T) checkWasNull(stream, Integer.valueOf(stream.readInt()));
    } else if (type == Long.class) {
      return (T) checkWasNull(stream, Long.valueOf(stream.readLong()));
    } else if (type == Short.class) {
      return (T) checkWasNull(stream, Short.valueOf(stream.readShort()));
    } else if (type == String.class) {
      return (T) stream.readString();
    } else if (type == Time.class) {
      return (T) stream.readTime();
    } else if (type == Timestamp.class) {
      return (T) stream.readTimestamp();
    } else if (type == YearToMonth.class) {
      String string = stream.readString();
      return (T) (string == null ? null : YearToMonth.valueOf(string));
    } else if (type == DayToSecond.class) {
      String string = stream.readString();
      return (T) (string == null ? null : DayToSecond.valueOf(string));
    } else if (type == UByte.class) {
      String string = stream.readString();
      return (T) (string == null ? null : UByte.valueOf(string));
    } else if (type == UShort.class) {
      String string = stream.readString();
      return (T) (string == null ? null : UShort.valueOf(string));
    } else if (type == UInteger.class) {
      String string = stream.readString();
      return (T) (string == null ? null : UInteger.valueOf(string));
    } else if (type == ULong.class) {
      String string = stream.readString();
      return (T) (string == null ? null : ULong.valueOf(string));
    }

    // The type byte[] is handled earlier. byte[][] can be handled here
    else if (type.isArray()) {
      Array result = stream.readArray();
      return (T) (result == null ? null : result.getArray());
    } else if (ArrayRecord.class.isAssignableFrom(type)) {
      return (T)
          getArrayRecord(configuration, stream.readArray(), (Class<? extends ArrayRecord<?>>) type);
    } else if (EnumType.class.isAssignableFrom(type)) {
      return getEnumType(type, stream.readString());
    } else if (MasterDataType.class.isAssignableFrom(type)) {
      return (T) getMasterDataType(type, stream.readObject());
    } else if (UDTRecord.class.isAssignableFrom(type)) {
      return (T) stream.readObject();
    } else {
      return (T) stream.readObject();
    }
  }
Beispiel #13
0
  Nvl(Field<T> arg1, Field<T> arg2) {
    super("nvl", arg1.getDataType(), arg1, arg2);

    this.arg1 = arg1;
    this.arg2 = arg2;
  }
Beispiel #14
0
    MutablePOJOMapper(Constructor<? extends E> constructor, E instance) {
      this.constructor = accessible(constructor);
      this.useAnnotations = hasColumnAnnotations(configuration, type);
      this.members = new List[fields.length];
      this.methods = new List[fields.length];
      this.nested = new HashMap<String, List<RecordMapper<R, Object>>>();
      this.instance = instance;

      Map<String, Field<?>[]> nestedFields = new HashMap<String, Field<?>[]>();
      for (int i = 0; i < fields.length; i++) {
        Field<?> field = fields[i];
        String name = field.getName();

        // Annotations are available and present
        if (useAnnotations) {
          members[i] = getAnnotatedMembers(configuration, type, name);
          methods[i] = getAnnotatedSetters(configuration, type, name);
        }

        // No annotations are present
        else {
          int dot = name.indexOf('.');

          // A nested mapping is applied
          if (dot > -1) {
            String prefix = name.substring(0, dot);

            Field<?>[] f = nestedFields.get(prefix);
            if (f == null) {
              f = nCopies(fields.length, field("")).toArray(new Field[fields.length]);
              nestedFields.put(prefix, f);
            }

            f[i] = field(name(name.substring(prefix.length() + 1)), field.getDataType());

            members[i] = Collections.emptyList();
            methods[i] = Collections.emptyList();
          }

          // A top-level mapping is applied
          else {
            members[i] = getMatchingMembers(configuration, type, name);
            methods[i] = getMatchingSetters(configuration, type, name);
          }
        }
      }

      for (Entry<String, Field<?>[]> entry : nestedFields.entrySet()) {
        String prefix = entry.getKey();
        List<RecordMapper<R, Object>> list = new ArrayList<RecordMapper<R, Object>>();

        for (java.lang.reflect.Field member : getMatchingMembers(configuration, type, prefix)) {
          list.add(
              new RemovingPrefixRecordMapper(
                  new DefaultRecordMapper<R, Object>(
                      new Fields<R>(entry.getValue()), member.getType(), null, configuration),
                  fields,
                  prefix));
        }

        for (Method method : getMatchingSetters(configuration, type, prefix)) {
          list.add(
              new RemovingPrefixRecordMapper(
                  new DefaultRecordMapper<R, Object>(
                      new Fields<R>(entry.getValue()),
                      method.getParameterTypes()[0],
                      null,
                      configuration),
                  fields,
                  prefix));
        }

        nested.put(prefix, list);
      }
    }
Beispiel #15
0
  @SuppressWarnings("unchecked")
  @Override
  final Field<T> getFunction0(Configuration configuration) {
    SQLDialect dialect = configuration.getDialect();

    // ---------------------------------------------------------------------
    // XXX: Bitwise operators
    // ---------------------------------------------------------------------

    // DB2, H2 and HSQLDB know functions, instead of operators
    if (BIT_AND == operator && asList(DB2, H2, HSQLDB, ORACLE).contains(dialect)) {
      return function("bitand", getDataType(), getArguments());
    } else if (BIT_AND == operator && FIREBIRD == dialect) {
      return function("bin_and", getDataType(), getArguments());
    } else if (BIT_XOR == operator && asList(DB2, H2, HSQLDB).contains(dialect)) {
      return function("bitxor", getDataType(), getArguments());
    } else if (BIT_XOR == operator && FIREBIRD == dialect) {
      return function("bin_xor", getDataType(), getArguments());
    } else if (BIT_OR == operator && asList(DB2, H2, HSQLDB).contains(dialect)) {
      return function("bitor", getDataType(), getArguments());
    } else if (BIT_OR == operator && FIREBIRD == dialect) {
      return function("bin_or", getDataType(), getArguments());
    }

    // Oracle has to simulate or/xor
    else if (BIT_OR == operator && ORACLE == dialect) {
      return lhs.sub(bitAnd(lhsAsNumber(), rhsAsNumber())).add(rhsAsNumber());
    }

    // ~(a & b) & (a | b)
    else if (BIT_XOR == operator && asList(ORACLE, SQLITE).contains(dialect)) {
      return (Field<T>)
          bitAnd(bitNot(bitAnd(lhsAsNumber(), rhsAsNumber())), bitOr(lhsAsNumber(), rhsAsNumber()));
    }

    // Many dialects don't support shifts. Use multiplication/division instead
    else if (SHL == operator
        && asList(ASE, DB2, H2, HSQLDB, INGRES, ORACLE, SQLSERVER, SYBASE).contains(dialect)) {
      return lhs.mul(Factory.power(two(), rhsAsNumber()));
    } else if (SHR == operator
        && asList(ASE, DB2, H2, HSQLDB, INGRES, ORACLE, SQLSERVER, SYBASE).contains(dialect)) {
      return lhs.div(Factory.power(two(), rhsAsNumber()));
    }

    // Some dialects support shifts as functions
    else if (SHL == operator && FIREBIRD == dialect) {
      return function("bin_shl", getDataType(), getArguments());
    } else if (SHR == operator && FIREBIRD == dialect) {
      return function("bin_shr", getDataType(), getArguments());
    }

    // These operators are not supported in any dialect
    else if (BIT_NAND == operator) {
      return (Field<T>) bitNot(bitAnd(lhsAsNumber(), rhsAsNumber()));
    } else if (BIT_NOR == operator) {
      return (Field<T>) bitNot(bitOr(lhsAsNumber(), rhsAsNumber()));
    } else if (BIT_XNOR == operator) {
      return (Field<T>) bitNot(bitXor(lhsAsNumber(), rhsAsNumber()));
    }

    // ---------------------------------------------------------------------
    // XXX: Date time arithmetic operators
    // ---------------------------------------------------------------------

    // [#585] Date time arithmetic for numeric or interval RHS
    else if (asList(ADD, SUBTRACT).contains(operator)
        && lhs.getDataType().isDateTime()
        && (rhs.get(0).getDataType().isNumeric() || rhs.get(0).getDataType().isInterval())) {

      return new DateExpression();
    }

    // ---------------------------------------------------------------------
    // XXX: Other operators
    // ---------------------------------------------------------------------

    // Use the default operator expression for all other cases
    else {
      return new DefaultExpression();
    }
  }
Beispiel #16
0
  FieldAlias(Field<T> field, String alias) {
    super(alias, field.getDataType());

    this.alias = new Alias<Field<T>>(field, alias, false);
  }
Beispiel #17
0
  Neg(Field<T> field, ExpressionOperator operator) {
    super(operator.toSQL() + field.getName(), field.getDataType());

    this.operator = operator;
    this.field = field;
  }