protected void writeValue(Value value, JsonGenerator generator) throws IOException { switch (value.getType()) { case NULL: generator.writeNull(); break; case STRING: generator.writeString(value.asString()); break; case BOOLEAN: generator.writeBoolean(value.asBoolean()); break; case BINARY: generator.writeBinary(value.asBytes()); break; case INTEGER: generator.writeNumber(value.asInteger()); break; case LONG: generator.writeNumber(value.asLong()); break; case FLOAT: generator.writeNumber(value.asFloat()); break; case DOUBLE: generator.writeNumber(value.asDouble()); break; case BIG_INTEGER: generator.writeNumber(value.asBigInteger()); break; case DECIMAL:
@Override public boolean equals(Object obj) { if (obj == this) return true; if (obj instanceof Value) { Value that = (Value) obj; if (this.isNumber() && that.isNumber()) { if (this.isLong()) return this.asLong().equals(that.asLong()); if (this.isDouble()) return this.asDouble().equals(that.asDouble()); if (this.isInteger()) return this.asInteger().equals(that.asInteger()); if (this.isFloat()) return this.asFloat().equals(that.asFloat()); if (this.isBigDecimal()) return this.asBigDecimal().equals(that.asBigDecimal()); if (this.isBigInteger()) return this.asBigInteger().equals(that.asBigInteger()); } return this.value.equals(that.asObject()); } // Compare the value straight away ... return this.value.equals(obj); }
/** * Find a document at the given path and obtain a stream over its fields. This will return an empty stream when: * <ul> * <li>a value does not exist in this document at the supplied path; or</li> * <li>a non-document value does exist in this document at the supplied path; or</li> * <li>a document value does exist in this document at the supplied path, but that document is empty</li> * </ul> * * @param path the path to the contained document * @return the stream of fields in the document at the given path; never null */ default Stream<Field> children(Path path) { Value parent = find(path).orElse(Value.create(Document.create())); if (!parent.isDocument()) return Stream.empty(); return parent.asDocument().stream(); }
@Override public Document asDocument() { return value.isDocument() ? value.asDocument() : null; }
/** * If a value is a boolean value, invoke the specified consumer with the value, otherwise do nothing. * * @param consumer block to be executed if the value is a boolean * @return true if the block was called, or false otherwise */ default boolean ifBoolean(Consumer<Boolean> consumer) { if (isBoolean()) { consumer.accept(asBoolean()); return true; } return false; }
@SuppressWarnings("unchecked") @Override public int compareTo(Value that) { if (Value.isNull(that)) return 1; if ( this.isBoolean() && that.isBoolean() ) { return this.asBoolean().compareTo(that.asBoolean()); } if (this.isNumber() && that.isNumber()) { if (this.isLong()) return this.asLong().compareTo(that.asLong()); if (this.isDouble()) return this.asDouble().compareTo(that.asDouble()); if (this.isInteger()) return this.asInteger().compareTo(that.asInteger()); if (this.isFloat()) return this.asFloat().compareTo(that.asFloat()); if (this.isBigDecimal()) return this.asBigDecimal().compareTo(that.asBigDecimal()); return this.asBigInteger().compareTo(that.asBigInteger()); } if ( this.isDocument() && that.isDocument()) { return this.asDocument().compareTo(that.asDocument()); } if ( this.isArray() && that.isArray() ) { return this.asArray().compareTo(that.asArray()); } Comparable<Object> thisValue = (Comparable<Object>)this.asObject(); Comparable<Object> thatValue = (Comparable<Object>)((ComparableValue)that.comparable()).asObject(); if ( thisValue.getClass().isAssignableFrom(thatValue.getClass())) { return thisValue.compareTo(thatValue); } else if (thatValue.getClass().isAssignableFrom(thisValue.getClass())) { return thatValue.compareTo(thisValue) * -1; // correct for the reversed comparison } return ((Comparable<Object>) this.value).compareTo(that.asObject()); }
if (rawValue.isNull()) { final String dataString = rawValue.asString(); PgArray arrayData = new PgArray(connection.get(), type.getOid(), dataString); Object deserializedArray = arrayData.getArray(); return rawValue.asBoolean(); return rawValue.asString(); case "serial4": case "oid": return rawValue.asInteger(); return rawValue.asLong(); return rawValue.isNumber() ? rawValue.asFloat() : Float.valueOf(rawValue.asString()); return rawValue.isNumber() ? rawValue.asDouble() : Double.valueOf(rawValue.asString()); if (rawValue.isInteger()) { return new SpecialValueDecimal(new BigDecimal(rawValue.asInteger())); else if (rawValue.isLong()) { return new SpecialValueDecimal(new BigDecimal(rawValue.asLong())); else if (rawValue.isBigInteger()) { return new SpecialValueDecimal(new BigDecimal(rawValue.asBigInteger()));
@Override public BigDecimal asBigDecimal() { if (value.isBigDecimal()) return value.asBigDecimal(); if (value.isBigInteger()) return new BigDecimal(value.asBigInteger()); if (value.isInteger() || value.isLong()) return BigDecimal.valueOf(asLong().longValue()); if (value.isFloat() || value.isDouble()) return BigDecimal.valueOf(asDouble().doubleValue()); if (value.isString()) { try { return new BigDecimal(asString()); } catch (NumberFormatException e) { } } return null; }
default void forEach(BiConsumer<Path, Value> consumer) { Path root = Path.root(); stream().forEach((field) -> { Path path = root.append(field.getName().toString()); Value value = field.getValue(); if (value.isDocument()) { value.asDocument().forEach((p, v) -> { consumer.accept(path.append(p), v); }); } else if (value.isArray()) { value.asArray().forEach((entry) -> { consumer.accept(path.append(Integer.toString(entry.getIndex())), entry.getValue()); }); } else { consumer.accept(path, value); } }); }
@Override public void processMessage(ByteBuffer buffer, ReplicationMessageProcessor processor, TypeRegistry typeRegistry) throws SQLException, InterruptedException { try { if (!buffer.hasArray()) { throw new IllegalStateException("Invalid buffer received from PG server during streaming replication"); } final byte[] source = buffer.array(); final byte[] content = Arrays.copyOfRange(source, buffer.arrayOffset(), source.length); final Document message = DocumentReader.floatNumbersAsTextReader().read(content); LOGGER.debug("Message arrived for decoding {}", message); final long txId = message.getLong("xid"); final String timestamp = message.getString("timestamp"); final long commitTime = dateTime.systemTimestamp(timestamp); final Array changes = message.getArray("change"); Iterator<Entry> it = changes.iterator(); while (it.hasNext()) { Value value = it.next().getValue(); processor.process(new Wal2JsonReplicationMessage(txId, commitTime, value.asDocument(), containsMetadata, !it.hasNext(), typeRegistry)); } } catch (final IOException e) { throw new ConnectException(e); } }
@Override public BigInteger asBigInteger() { if (value.isBigInteger()) return value.asBigInteger(); if (value.isBigDecimal()) return value.asBigDecimal().toBigInteger(); if (value instanceof Number) return BigInteger.valueOf(asLong().longValue()); if (value.isString()) { try { return new BigInteger(asString()); } catch (NumberFormatException e) { } } return null; }
/** * Get the integer value in this document for the given field name. * * @param fieldName The name of the field * @return The integer field value, if found, or null if there is no such field or if the value is not an integer */ default Integer getInteger(CharSequence fieldName) { Value value = get(fieldName); return value != null && value.isInteger() ? value.asInteger() : null; }
/** * Get the integer value in this document for the given field name. * * @param fieldName The name of the field * @return The long field value, if found, or null if there is no such field or if the value is not a long value */ default Long getLong(CharSequence fieldName) { Value value = get(fieldName); return value != null && value.isLong() ? value.asLong() : null; }
@Override public Number asNumber() { if (value.isNumber()) return value.asNumber(); if (value.isString()) { String str = value.asString(); Number number = Strings.asNumber(str); if ( number instanceof Short ) { // Shorts aren't allowed, so just use an integer ... number = Integer.valueOf(number.intValue()); } return number; } return null; }