@Override public int compareTo(Array that) { if (that == null) return 1; int size = this.size(); if (size != that.size()) return size - that.size(); Array thatArray = that; for (int i = 0; i != size; ++i) { Value thatValue = thatArray.get(i); Value thisValue = get(i); int diff = thatValue.compareTo(thisValue); if (diff != 0) return diff; } return 0; }
/** * Adds the integer value to the end of this array. * * @param value the integer value; may not be null * @return this array to allow for chaining methods */ default Array add(int value) { add(Value.create(value)); return this; }
public Array toArray() { List<Value> values = changes.stream() .map(TableChange::toDocument) .map(Value::create) .collect(Collectors.toList()); return Array.create(values); }
/** * Set the value for the field with the given name to be a new, empty array. * * @param index the index of the field; must be greater than or equal to 0 or less than or equal to {@link #size() size} * @return The array that was just created; never null */ default Array setArray(int index) { return setArray(index, Array.create()); }
/** * Set the value for the field with the given name to be the supplied array. * * @param index the index of the field; must be greater than or equal to 0 or less than or equal to {@link #size() size} * @param values the (valid) values for the array * @return The array that was just set as the value for the named field; never null and may or may not be the same * instance as the supplied <code>array</code>. */ default Array setArray(int index, Value... values) { Array array = Array.create(values); setValue(index, Value.create(array)); return array; }
/** * Transform all of the field values using the supplied {@link BiFunction transformer function}. * * @param transformer the transformer that should be used to transform each field value; may not be null * @return this array with transformed fields, or this document if the transformer changed none of the values */ default Array transform(BiFunction<Integer, Value, Value> transformer) { for (int i = 0; i != size(); ++i) { Value existing = get(i); Value updated = transformer.apply(Integer.valueOf(i), existing); if (updated == null) updated = Value.nullValue(); if (updated != existing) { setValue(i, updated); } } return this; }
/** * Gets the value in this document for the given field name. * * @param index the index * @param defaultValue the default value to return if there is no such entry * @return The value if found or <code>defaultValue</code> if there is no such entry */ default Value get(int index, Object defaultValue) { Value value = get(index); return value != null ? value : Value.create(defaultValue); }
int expectedBatch = 1; int expectedRecord = 0; Iterator<Array.Entry> docs = expected.iterator(); while (docs.hasNext()) { Document doc = docs.next().getValue().asDocument(); assertThat(keySchema.getBoolean("optional")).isEqualTo(false); Array keySchemaFields = keySchema.getArray("fields"); Document keyIdField = keySchemaFields.get(0).asDocument(); assertRequiredFieldSchema(keyIdField, "id", Schema.Type.INT32); assertThat(valueSchema.getBoolean("optional")).isEqualTo(false); Array valueSchemaFields = valueSchema.getArray("fields"); Document batchField = valueSchemaFields.get(0).asDocument(); assertRequiredFieldSchema(batchField, "batch", Schema.Type.INT32); Document recordField = valueSchemaFields.get(1).asDocument(); assertRequiredFieldSchema(recordField, "record", Schema.Type.INT32);
String nextSegment = path.segment(missingIndex + 1); // can always find next segment 'path' (not 'parentPath')... if (Path.Segments.isArrayIndex(nextSegment)) { return Optional.of(Value.create(Array.create())); } else { return Optional.of(Value.create(Document.create())); Array array = parentValue.asArray(); if (Path.Segments.isAfterLastIndex(lastSegment)) { array.add(value); } else { int index = Path.Segments.asInteger(lastSegment).get(); array.setValue(index, 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); } }
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); } }); }
/** * Sets on this object all name/value pairs from the supplied object. If the supplied object is null, this method does * nothing. * * @param values the values to be added to this array * @return this array to allow for chaining methods */ default Array addAll(Value... values) { if (values != null) { addAll(Stream.of(values)); } return this; }
/** * Transform all of the field values using the supplied {@link BiFunction transformer function}. * * @param transformer the transformer that should be used to transform each field value; may not be null * @return this array with transformed fields, or this document if the transformer changed none of the values */ default Array transform(BiFunction<Integer, Value, Value> transformer) { for (int i = 0; i != size(); ++i) { Value existing = get(i); Value updated = transformer.apply(Integer.valueOf(i), existing); if (updated == null) updated = Value.nullValue(); if (updated != existing) { setValue(i, updated); } } return this; }
/** * Determine whether this object has an entry at the given index and the value is null. * * @param index the index * @return <code>true</code> if the entry exists but is null, or false otherwise * @see #isNullOrMissing(int) */ default boolean isNull(int index) { Value value = get(index); return value != null ? value.isNull() : false; }
int expectedBatch = 1; int expectedRecord = 0; Iterator<Array.Entry> docs = expected.iterator(); while (docs.hasNext()) { Document doc = docs.next().getValue().asDocument(); assertThat(keySchema.getBoolean("optional")).isEqualTo(false); Array keySchemaFields = keySchema.getArray("fields"); Document keyIdField = keySchemaFields.get(0).asDocument(); assertRequiredFieldSchema(keyIdField, "id", Schema.Type.INT32); assertThat(valueSchema.getBoolean("optional")).isEqualTo(false); Array valueSchemaFields = valueSchema.getArray("fields"); Document batchField = valueSchemaFields.get(0).asDocument(); assertRequiredFieldSchema(batchField, "batch", Schema.Type.INT32); Document recordField = valueSchemaFields.get(1).asDocument(); assertRequiredFieldSchema(recordField, "record", Schema.Type.INT32);
String nextSegment = path.segment(missingIndex + 1); // can always find next segment 'path' (not 'parentPath')... if (Path.Segments.isArrayIndex(nextSegment)) { return Optional.of(Value.create(Array.create())); } else { return Optional.of(Value.create(Document.create())); Array array = parentValue.asArray(); if (Path.Segments.isAfterLastIndex(lastSegment)) { array.add(value); } else { int index = Path.Segments.asInteger(lastSegment).get(); array.setValue(index, value);