All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oracle.nosql.driver.values.FieldValue Maven / Gradle / Ivy

There is a newer version: 5.4.16
Show newest version
/*-
 * Copyright (c) 2011, 2020 Oracle and/or its affiliates.  All rights reserved.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 *  https://oss.oracle.com/licenses/upl/
 */

package oracle.nosql.driver.values;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Timestamp;

import oracle.nosql.driver.JsonParseException;
import oracle.nosql.driver.ops.serde.BinaryProtocol;

/**
 * FieldValue is the base class of all data items in the Oracle NoSQL
 * Database Cloud system.  Each data item is an instance of FieldValue
 * allowing access to its type and its value as well as additional
 * utility methods that operate on FieldValue.
 * 

* FieldValue instances are typed, based on the {@link Type} enumeration. The * type system is similar to that of JSON with extensions. It is a subset of * the database types in Oracle NoSQL Database in that these objects do not * inherently conform to a fixed schema and some of the database types, such * as RECORD and ENUM, require a schema. The mappings of types is described * * here * * and is not reproduced in this documentation. *

* FieldValue instances used for put operations are not validated against the * target table schema in the driver. Validation happens where the table schema * is available. If an instance does not match the target table an exception is * thrown. *

* Returned FieldValue instances always conform to a table schema, or to the * shape implied by a query projection. *

* FieldValue instances are created in several ways: *

    *
  • From JSON input. In this path the JSON is parsed and mapped to * correspondings types.
  • *
  • Construction. Applications can construct instances manually, adding * and setting fields and types as needed. This mechanism can be more efficient * than parsing from JSON and it gives the application more control over the * types used when the mapping from JSON may not be precise.
  • *
  • Returned by operations on a table. These instances are created internally * by operations that return data and will have the schema implied by the table * or query.
  • *
*

* There are special cases for handling types that are not in the JSON type * system when creating a FieldValue instance from JSON. These are described * in the documentation for {@link #createFromJson}. *

* Numeric values are an extension to JSON which has only a single numeric type, * Number. For this reason the system is generous in mapping numeric types among * one another and will allow any lossless mapping without error. Mappings * default to the most efficient valid format. *

* FieldValue instances are not thread-safe. On input, they should not be reused * until the operation that uses them has returned. */ public abstract class FieldValue implements Comparable { /** * The type of a field. * These types correspond to the fundamental Oracle NoSQL Database types. */ public enum Type { /** An array of FieldValue instances */ ARRAY, /** A binary value */ BINARY, /** A boolean value */ BOOLEAN, /** A double value */ DOUBLE, /** An integer value */ INTEGER, /** A long value */ LONG, /** A map of FieldValue instances */ MAP, /** A string value */ STRING, /** A timestamp */ TIMESTAMP, /** A number value */ NUMBER, /** A JSON null value */ JSON_NULL, /** A null value, used only by index keys */ NULL, /** @hidden An empty, or missing value, used only by index keys */ EMPTY; } public FieldValue() { } /** * Returns the type of the object * * @return the type */ public abstract Type getType(); /** * Returns an integer value for the field if the value is an * IntegerValue * * @return an integer value * * @throws ClassCastException if this is not an IntegerValue */ public int getInt() { return asInteger().getValue(); } /** * Returns a long value for the field if the value is a * LongValue or IntegerValue * * @return a long value * * @throws ClassCastException if the value cannot be cast to long without * loss of precision */ public long getLong() { return asLong().getValue(); } /** * Returns a double value for the field if the value is a * DoubleValue * * @return a double value * * @throws ClassCastException if this is not a DoubleValue */ public double getDouble() { return asDouble().getValue(); } /** * Returns a BigDecimal value for the field if the value is numeric * * @return a number value * * @throws ClassCastException if this is not numeric */ public BigDecimal getNumber() { return asNumber().getValue(); } /** * Casts a numeric value to double, possibly with loss of information about * magnitude, precision or sign. * * @return a double value * * @throws ClassCastException if this value is not numeric */ public double castAsDouble() { throw new ClassCastException( "Value can not be cast to a double: " + getClass()); } /** * Returns a binary byte array value for the field if the value is * binary * * @return a byte array * * @throws ClassCastException if this is not a BinaryValue */ public byte[] getBinary() { return asBinary().getValue(); } /** * Returns a boolean value for the field if the value is a boolean * * @return the boolean value * * @throws ClassCastException if this is not a BooleanValue */ public boolean getBoolean() { return asBoolean().getValue(); } /** * Returns a String value for the field if the value is a * StringValue * * @return a String value * * @throws ClassCastException if this is not a StringValue */ public String getString() { return asString().getValue(); } /** * Returns a TimestampValue as a {@link java.sql.Timestamp} value. * * @return a Timestamp value * * @throws ClassCastException if this is not a Timestamp */ public Timestamp getTimestamp() { return asTimestamp().getValue(); } /** * Casts the object to IntegerValue. * * @return an IntegerValue * * @throws ClassCastException if this is not an IntegerValue */ public IntegerValue asInteger() { return (IntegerValue) this; } /** * Casts to StringValue. * * @return a StringValue * * @throws ClassCastException if this is not a StringValue */ public StringValue asString() { return (StringValue) this; } /** * Casts the object to LongValue. * * @return a LongValue * * @throws ClassCastException if this is not a LongValue */ public LongValue asLong() { return (LongValue) this; } /** * Casts the object to NumberValue. * * @return a NumberValue * * @throws ClassCastException if this is not a NumberValue */ public NumberValue asNumber() { return (NumberValue) this; } /** * Casts the object to TimestampValue. This method accepts objects * of type {@link Type#TIMESTAMP}, {@link Type#STRING}, * {@link Type#INTEGER} and {@link Type#LONG}. * In the case of {@link Type#STRING} the value is parsed as an * ISO8601 timestamp value and if valid, accepted. In the numeric cases * the value is interpreted as milliseconds since the Epoch, * "1970-01-01T00:00:00". * * @return a TimestampValue * * @throws ClassCastException if this is not a TimestampValue */ public TimestampValue asTimestamp() { if (getType() == Type.TIMESTAMP) { return (TimestampValue)this; } else if (getType() == Type.STRING) { return new TimestampValue(getString()); } else if (getType() == Type.INTEGER || getType() == Type.LONG) { return new TimestampValue(getLong()); } throw new ClassCastException("Can't cast to a TimestampValue"); } /** * Casts the object to BooleanValue. * * @return a BooleanValue * * @throws ClassCastException if this is not a BooleanValue */ public BooleanValue asBoolean() { return (BooleanValue) this; } /** * Casts the object to ArrayValue. * * @return a ArrayValue * * @throws ClassCastException if this is not a ArrayValue */ public ArrayValue asArray() { return (ArrayValue) this; } /** * Casts the object to BinaryValue. * * @return a BinaryValue * * @throws ClassCastException if this is not a BinaryValue */ public BinaryValue asBinary() { return (BinaryValue) this; } /** * Casts the object to MapValue. * * @return a MapValue * * @throws ClassCastException if this is not a MapValue */ public MapValue asMap() { return (MapValue) this; } /** * Casts to DoubleValue. * * @return a DoubleValue * * @throws ClassCastException if this is not a DoubleValue */ public DoubleValue asDouble() { return (DoubleValue) this; } /** * Casts to JsonNullValue. * * @return a JsonNullValue * * @throws ClassCastException if this is not a JsonNullValue */ public JsonNullValue asJsonNull() { return (JsonNullValue) this; } /** * Casts to NullValue. * * @return a NullValue * * @throws ClassCastException if this is not a NullValue */ public NullValue asNull() { return (NullValue) this; } /** * @hidden * * Casts to EmptyValue. * * @return a EmptyValue * * @throws ClassCastException if this is not a EmptyValue */ public EmptyValue asEmpty() { return (EmptyValue) this; } /** * Returns whether this is an atomic value, that is, not an array or map * value. * * @return Whether this is an atomic value. */ public boolean isAtomic() { Type t = getType(); return (t != Type.ARRAY && t != Type.MAP); } /** * Returns whether this is a numeric value (integer, long, double, * or number) * value. * * @return Whether this is a numeri value. */ public boolean isNumeric() { Type t = getType(); switch(t) { case INTEGER: case LONG: case DOUBLE: case NUMBER: return true; default: return false; } } /** * Returns whether this is an SQL NULL value. * * @return Whether this is an SQL NULL value. */ public boolean isNull() { return this == NullValue.getInstance(); } /** * Returns whether this is a json null value. * * @return Whether this is a json null value. */ public boolean isJsonNull() { return this == JsonNullValue.getInstance(); } /** * @hidden * @return true if is empty */ public boolean isEMPTY() { return this == EmptyValue.getInstance(); } /** * Returns a JSON representation of the value using a default * configuration for output format. * * @return the JSON representation of this value. */ public String toJson() { return toJson(null); } /** * Returns a JSON representation of the value using the options, if * specified. * * @param options configurable options used to affect the JSON output * format of some data types. May be null. * * @return the JSON representation of this value. */ public String toJson(JsonOptions options) { FieldValueEventHandler handler = (options != null && options.getPrettyPrint() ? new JsonPrettySerializer(options) : new JsonSerializer(options)); try { FieldValueEventHandler.generate(this, handler); return handler.toString(); } catch (IOException ioe) { throw new IllegalArgumentException( "Failed to serialize FieldValue into JSON: " + ioe.getMessage()); } } /** * Returns a String representation of the value, consistent with * representation as JSON strings. * * @return the String value */ @Override public String toString() { return toJson(); } /** * Returns the serialized size of this value. This value can be used to * estimate amount of throughput used by a sample value. This size will * always be larger than the actual space consumed because the server * serializes in a more compact format. * * @return the size, in bytes, used by the serialized format of this * value. */ public int getSerializedSize() { return BinaryProtocol.getSerializedSize(this); } /** * @hidden * @return size of value in bytes */ public abstract long sizeof(); /** * Constructs a new FieldValue instance based on the JSON string provided. *

* Two of the types in the driver type system are not part of the JSON data * model -- TIMESTAMP and BINARY -- and will never be created using this * method. If a table schema includes these types, as well as the ENUM type * supported by Oracle NoSQL Database, they should be input as follows: *

    *
  • BINARY should be a Base64-encoded String
  • *
  • TIMESTAMP may be either a long value representing milliseconds since * January 1, 1970, or a String value that is in a valid ISO 8601 formatted * string. *
  • *
  • ENUM should be a String that matches one of the valid enumeration * values
  • *
* If one of these types is to be used inside a JSON data type, there is no * schema in the database server and the type cannot be inferred by the system * and interpretation is left to the application. * * @param jsonInput a JSON formatted String * * @param options configurable options used to affect the JSON output * format of some data types. May be null. * * @return a new FieldValue instance representing the JSON string * * @throws JsonParseException if the string is not valid JSON */ public static FieldValue createFromJson(String jsonInput, JsonOptions options) { return JsonUtils.createValueFromJson(jsonInput, options); } /** * Constructs a new FieldValue instance based on JSON read from the * Reader provided. * * @param jsonInput a Reader containing JSON * * @param options configurable options used to affect the JSON output * format of some data types. May be null. * * @return a new FieldValue instance representing the JSON string * * @throws JsonParseException if the input is not valid JSON */ public static FieldValue createFromJson(Reader jsonInput, JsonOptions options) { return JsonUtils.createValueFromJson(jsonInput, options); } /** * Constructs a new FieldValue instance based on JSON read from the * InputStream provided. * * @param jsonInput an InputStream containing JSON * * @param options configurable options used to affect the JSON output * format of some data types. May be null. * * @return a new FieldValue instance representing the JSON string * * @throws JsonParseException if the input is not valid JSON */ public static FieldValue createFromJson(InputStream jsonInput, JsonOptions options) { return JsonUtils.createValueFromJson(jsonInput, options); } /* * Internal utility methods */ static void validateName(String name, FieldValue value) { if (name == null) { throw new IllegalArgumentException("Field name is null"); } if (value == null) { throw new IllegalArgumentException("FieldValue is null"); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy