Skip to content

Commit

Permalink
ledger-api: rename decimal field to numeric in value Proto (digital-a…
Browse files Browse the repository at this point in the history
…sset#2688)

* add Numeric.java

* ledger-api: rename `decimal` field to `numeric` in value protobuf

* Address Gerolf's comment

* ledger-api: add missing renammings

* ledger-api: relax syntax of numbers that can be sent as numerics

* extractor:  fix

* leger-api: change format of number though ledger api

* daml-lf: fix numeric regexp

* ledger: fix tests
  • Loading branch information
remyhaemmerle-da authored and mergify[bot] committed Aug 29, 2019
1 parent d26dcd8 commit 20649cf
Show file tree
Hide file tree
Showing 47 changed files with 207 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ case class Conversions(homePackageId: Ref.PackageId) {
.build
)
case V.ValueInt64(v) => builder.setInt64(v)
case V.ValueNumeric(d) => builder.setDecimal(Numeric.toUnscaledString(d))
case V.ValueNumeric(d) => builder.setDecimal(Numeric.toString(d))
case V.ValueText(t) => builder.setText(t)
case V.ValueTimestamp(ts) => builder.setTimestamp(ts.micros)
case V.ValueDate(d) => builder.setDate(d.days)
Expand Down
2 changes: 1 addition & 1 deletion daml-assistant/integration-tests/src/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ quickstartTests quickstartDir mvnDir = testGroup "quickstart"
req <- pure req { requestHeaders = [(hContentType, "application/json")] }
resp <- httpLbs req manager
responseBody resp @?=
"{\"0\":{\"issuer\":\"EUR_Bank\",\"owner\":\"Alice\",\"currency\":\"EUR\",\"amount\":100.0,\"observers\":[]}}"
"{\"0\":{\"issuer\":\"EUR_Bank\",\"owner\":\"Alice\",\"currency\":\"EUR\",\"amount\":100.0000000000,\"observers\":[]}}"
-- waitForProcess' will block on Windows so we explicitly kill the process.
terminateProcess ph
-- waitForProcess' will block on Windows so we explicitly kill the process.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ abstract class NumericModule {
Either.cond(
x.precision <= maxPrecision,
cast(x),
s"Out-of-bounds (Numeric ${x.scale}) $x"
s"Out-of-bounds (Numeric ${x.scale}) ${toString(x)}"
)

/**
Expand Down Expand Up @@ -109,7 +109,7 @@ abstract class NumericModule {
*/
final def toLong(x: Numeric): Either[String, Long] =
Try(x.setScale(0, ROUND_DOWN).longValueExact()).toEither.left.map(
_ => s"(Numeric ${x.scale}) $x does not fit into an Int64",
_ => s"(Numeric ${x.scale}) ${toString(x)} does not fit into an Int64",
)

/**
Expand Down Expand Up @@ -144,7 +144,7 @@ abstract class NumericModule {
if (!(0 <= scale && scale <= maxPrecision))
Left(s"Bad scale $scale, must be between 0 and $maxPrecision")
else if (!(x.stripTrailingZeros.scale <= scale))
Left(s"Cannot represent $x as (Numeric $scale) without lost of precision")
Left(s"Cannot represent ${toString(x)} as (Numeric $scale) without lost of precision")
else
checkForOverflow(x.setScale(scale, ROUND_UNNECESSARY))

Expand Down Expand Up @@ -177,13 +177,13 @@ abstract class NumericModule {
* - the decimal point (".") to separate the integral part from the decimal part,
* - the decimal part of `x` with '0' padded to match the scale. The number of decimal digits must be the same as the scale.
*/
final def toString(x: Numeric): String = {
final def toString(x: BigDecimal): String = {
val s = x.toPlainString
if (x.scale == 0) s + "." else s
}

private val validScaledFormat =
"""-?([1-9]\d*|0).(\d*)""".r
"""-?([1-9]\d*|0)\.(\d*)""".r

/**
* Given a string representation of a decimal returns the corresponding Numeric, where the number of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ class NumericSpec
"999999999999999999999999999999999999999.",
"82845904523536028.7471352662497757247012",
"0.314159265358979323846264338327950288421",
"1E10",
"00.0",
"+0.1",
"1..0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.util.concurrent.TimeUnit

import com.digitalasset.ledger.api.v1.commands.{Command, CreateCommand, ExerciseCommand}
import com.digitalasset.ledger.api.v1.value.Value.Sum.{
Decimal,
Numeric,
Int64,
Party,
Text,
Expand All @@ -29,7 +29,7 @@ object ValueConversions {

implicit class StringValues(val s: String) extends AnyVal {
def asParty: Value = Value(Party(s))
def asDecimal: Value = Value(Decimal(s))
def asNumeric: Value = Value(Numeric(s))
def asText: Value = Value(Text(s))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ object LedgerValue {
case Sum.Bool(value) => V.ValueBool(value).right
case Sum.ContractId(value) => V.ValueContractId(value).right
case Sum.Int64(value) => V.ValueInt64(value).right
case Sum.Decimal(value) => lfdata.Decimal.fromString(value).disjunction map V.ValueNumeric
case Sum.Numeric(value) =>
lfdata.Numeric
.fromUnscaledBigDecimal(new java.math.BigDecimal(value))
.disjunction map V.ValueNumeric
case Sum.Text(value) => V.ValueText(value).right
case Sum.Timestamp(value) =>
lfdata.Time.Timestamp.fromLong(value).disjunction map V.ValueTimestamp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

package com.digitalasset.extractor.writers.postgresql

import com.digitalasset.daml.lf.data.{Decimal, Time => LfTime}
import com.digitalasset.daml.lf.data.{Time => LfTime}
import com.digitalasset.daml.lf.value.{Value => V}
import com.digitalasset.extractor.json.JsonConverters._
import com.digitalasset.extractor.Types._
Expand Down Expand Up @@ -305,8 +305,7 @@ object Queries {
case V.ValueNumeric(value) =>
// FixMe: https://github.com/digital-asset/daml/issues/2289
// For now all the ValueNumeric should have scale 10
// Adapt this code once it is possible to create Numerics with different scale
assert(value.scale == Decimal.scale)
// Check this code once it is possible to create Numerics with different scale
Fragment("?::numeric(38,10)", value: BigDecimal)
case V.ValueText(value) => Fragment("?", value)
case ts @ V.ValueTimestamp(_) => Fragment("?", ts)
Expand Down
4 changes: 2 additions & 2 deletions language-support/hs/bindings/src/DA/Ledger/Convert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ lowerValue = LL.Value . Just . \case
VContract c -> (LL.ValueSumContractId . unContractId) c
VList vs -> (LL.ValueSumList . LL.List . Vector.fromList . map lowerValue) vs
VInt i -> (LL.ValueSumInt64 . fromIntegral) i
VDecimal t -> LL.ValueSumDecimal $ Text.pack $ show t
VDecimal t -> LL.ValueSumNumeric $ Text.pack $ show t
VText t -> LL.ValueSumText t
VTime x -> (LL.ValueSumTimestamp . fromIntegral . unMicroSecondsSinceEpoch) x
VParty p -> (LL.ValueSumParty . unParty) p
Expand Down Expand Up @@ -355,7 +355,7 @@ raiseValue = \case
LL.ValueSumContractId c -> (return . VContract . ContractId) c
LL.ValueSumList vs -> (fmap VList . raiseList raiseValue . LL.listElements) vs
LL.ValueSumInt64 i -> (return . VInt . fromIntegral) i
LL.ValueSumDecimal t -> (return . VDecimal . read . Text.unpack) t
LL.ValueSumNumeric t -> (return . VDecimal . read . Text.unpack) t
LL.ValueSumText t -> (return . VText) t
LL.ValueSumTimestamp x -> (return . VTime . MicroSecondsSinceEpoch . fromIntegral) x
LL.ValueSumParty p -> (return . VParty . Party) p
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,12 @@ object TransactionGenerator {
(Sum.Int64(int64), new data.Int64(int64))
}

val decimalValueGen: Gen[(Sum.Decimal, data.Decimal)] = for {
val decimalValueGen: Gen[(Sum.Numeric, data.Numeric)] = for {
sign <- Gen.pick(1, List("", "+", "-"))
leading <- Gen.choose(1, 9)
decimals <- Gen.listOfN(37, Gen.choose(0, 9))
text = s"${sign.head}$leading${decimals.take(27).mkString}.${decimals.drop(27).mkString}"
} yield (Sum.Decimal(text), new data.Decimal(new java.math.BigDecimal(text)))
} yield (Sum.Numeric(text), new data.Numeric(new java.math.BigDecimal(text)))

val textValueGen: Gen[(Sum.Text, data.Text)] = Arbitrary.arbString.arbitrary.map { text =>
(Sum.Text(text), new data.Text(text))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,14 @@

package com.daml.ledger.javaapi.data;

import com.digitalasset.ledger.api.v1.ValueOuterClass;
import org.checkerframework.checker.nullness.qual.NonNull;

import java.math.BigDecimal;
import java.util.Objects;

public class Decimal extends Value {

private final BigDecimal value;
@Deprecated
public class Decimal extends Numeric {

public Decimal(@NonNull BigDecimal value) {
this.value = value;
}

public static Decimal fromProto(String decimal) {
return new Decimal(new BigDecimal(decimal));
}

@Override
public ValueOuterClass.Value toProto() {
return ValueOuterClass.Value.newBuilder().setDecimal(this.value.toPlainString()).build();
}

@NonNull
public BigDecimal getValue() {
return value;
}

@Override
public String toString() {
return "Decimal{" +
"value=" + value +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Decimal decimal = (Decimal) o;
return Objects.equals(value, decimal.value);
}

@Override
public int hashCode() {

return Objects.hash(value);
super(value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2019 The DAML Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.javaapi.data;

import com.digitalasset.ledger.api.v1.ValueOuterClass;
import org.checkerframework.checker.nullness.qual.NonNull;

import java.math.BigDecimal;
import java.util.Objects;

public class Numeric extends Value {

private final BigDecimal value;

public Numeric(@NonNull BigDecimal value) { this.value = value; }

public static Numeric fromProto(String numeric) {
return new Numeric(new BigDecimal(numeric));
}

@Override
public ValueOuterClass.Value toProto() {
return ValueOuterClass.Value.newBuilder().setNumeric(this.value.toPlainString()).build();
}

@NonNull
public BigDecimal getValue() {
return value;
}

@Override
public String toString() {
return "Numeric{" +
"value=" + value +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Numeric numeric = (Numeric) o;
return Objects.equals(value, numeric.value);
}

@Override
public int hashCode() {

return Objects.hash(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ public static Value fromProto(ValueOuterClass.Value value) {
return DamlList.fromProto(value.getList());
case INT64:
return new Int64(value.getInt64());
case DECIMAL:
return Decimal.fromProto(value.getDecimal());
case NUMERIC:
return Numeric.fromProto(value.getNumeric());
case TEXT:
return new Text(value.getText());
case TIMESTAMP:
Expand Down Expand Up @@ -87,10 +87,15 @@ public final Optional<Int64> asInt64() {
return (this instanceof Int64) ? Optional.of((Int64) this) : Optional.empty();
}

@Deprecated
public final Optional<Decimal> asDecimal() {
return (this instanceof Decimal) ? Optional.of((Decimal) this) : Optional.empty();
}

public final Optional<Numeric> asNumeric() {
return (this instanceof Numeric) ? Optional.of((Numeric) this) : Optional.empty();
}

public final Optional<Text> asText() {
return (this instanceof Text) ? Optional.of((Text) this) : Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ object Generators {

def decimalValueGen: Gen[ValueOuterClass.Value] =
Arbitrary.arbBigDecimal.arbitrary.map(d =>
ValueOuterClass.Value.newBuilder().setDecimal(d.bigDecimal.toPlainString).build())
ValueOuterClass.Value.newBuilder().setNumeric(d.bigDecimal.toPlainString).build())

def eventGen: Gen[EventOuterClass.Event] =
for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class ValueSpec extends FlatSpec with Matchers with GeneratorDrivenPropertyCheck
SumCase.BOOL -> (((_: Value).asBool(), "asBool")),
SumCase.CONTRACT_ID -> (((_: Value).asContractId(), "asContractId")),
SumCase.DATE -> (((_: Value).asDate(), "asDate")),
SumCase.DECIMAL -> (((_: Value).asDecimal(), "asDecimal")),
SumCase.NUMERIC -> (((_: Value).asNumeric(), "asNumeric")),
SumCase.INT64 -> (((_: Value).asInt64(), "asInt64")),
SumCase.LIST -> (((_: Value).asList(), "asList")),
SumCase.PARTY -> (((_: Value).asParty(), "asParty")),
Expand Down Expand Up @@ -66,7 +66,7 @@ class ValueSpec extends FlatSpec with Matchers with GeneratorDrivenPropertyCheck
assertConversions(SumCase.BOOL, Value.fromProto(boolValueGen.sample.get))
assertConversions(SumCase.CONTRACT_ID, Value.fromProto(contractIdValueGen.sample.get))
assertConversions(SumCase.DATE, Value.fromProto(dateValueGen.sample.get))
assertConversions(SumCase.DECIMAL, Value.fromProto(decimalValueGen.sample.get))
assertConversions(SumCase.NUMERIC, Value.fromProto(decimalValueGen.sample.get))
assertConversions(SumCase.INT64, Value.fromProto(int64ValueGen.sample.get))
assertConversions(SumCase.LIST, Value.fromProto(listValueGen.sample.get))
assertConversions(SumCase.PARTY, Value.fromProto(partyValueGen.sample.get))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void checkRecord(MyRecord myRecord) {
@Test
void deserializableFromRecord() {
Int64 int_ = new Int64(int64Value);
Decimal decimal = new Decimal(decimalValue);
Numeric decimal = new Numeric(decimalValue);
Text text = new Text(textValue);
Bool bool = new Bool(boolValue);
Party party = new Party(partyValue);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

package com.digitalasset

import java.math.BigDecimal
import java.time.temporal.ChronoField
import java.time.{Instant, LocalDate, ZoneOffset}

import com.digitalasset.daml.lf.data.Numeric
import com.daml.ledger.javaapi.data.{Unit => DamlUnit}
import org.scalatest.{FlatSpec, Matchers}
import wolpertinger.color.Grey
Expand All @@ -21,7 +23,7 @@ class CodegenLedgerTest extends FlatSpec with Matchers {
val glookofly = new Wolpertinger(
Alice,
3L,
BigDecimal(17.42).bigDecimal,
new BigDecimal("17.4200000000"),
"Glookofly",
true,
LocalDate.of(1583, 12, 8),
Expand All @@ -33,7 +35,7 @@ class CodegenLedgerTest extends FlatSpec with Matchers {
val sruquito = new Wolpertinger(
Alice,
1L,
BigDecimal(8.2).bigDecimal,
new BigDecimal("8.2000000000"),
"Sruquito",
true,
LocalDate.of(1303, 3, 19),
Expand Down Expand Up @@ -107,7 +109,8 @@ class CodegenLedgerTest extends FlatSpec with Matchers {
val wolpertinger :: _ = readActiveContracts(Wolpertinger.Contract.fromCreatedEvent)(client)

wolpertinger.agreementText.isPresent shouldBe true
wolpertinger.agreementText.get shouldBe s"${wolpertinger.data.name} has ${wolpertinger.data.wings} wings and is ${wolpertinger.data.age} years old."
wolpertinger.agreementText.get shouldBe s"${wolpertinger.data.name} has ${wolpertinger.data.wings} wings and is ${Numeric
.toUnscaledString(Numeric.assertFromUnscaledBigDecimal(wolpertinger.data.age))} years old."
}

it should "provide the key" in withClient { client =>
Expand All @@ -117,7 +120,7 @@ class CodegenLedgerTest extends FlatSpec with Matchers {

wolpertinger.key.isPresent shouldBe true
wolpertinger.key.get.owner shouldEqual "Alice"
wolpertinger.key.get.age shouldEqual java.math.BigDecimal.valueOf(17.42)
wolpertinger.key.get.age shouldEqual new BigDecimal("17.4200000000")
}

it should "be able to exercise by key" in withClient { client =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ object Types {
// ContractId is missing from the mapping because it's always used in its boxed form
val apiBoolean = ClassName.get(classOf[javaapi.data.Bool])
val apiInt64 = ClassName.get(classOf[javaapi.data.Int64])
val apiDecimal = ClassName.get(classOf[javaapi.data.Decimal])
val apiNumeric = ClassName.get(classOf[javaapi.data.Numeric])
val apiText = ClassName.get(classOf[javaapi.data.Text])
val apiTimestamp = ClassName.get(classOf[javaapi.data.Timestamp])
val apiParty = ClassName.get(classOf[javaapi.data.Party])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private[inner] object FromValueGenerator extends StrictLogging {
Map[PrimType, (String, Option[String])](
(PrimTypeBool, ("asBool", Some(".getValue()"))),
(PrimTypeInt64, ("asInt64", Some(".getValue()"))),
(PrimTypeDecimal, ("asDecimal", Some(".getValue()"))),
(PrimTypeDecimal, ("asNumeric", Some(".getValue()"))),
(PrimTypeText, ("asText", Some(".getValue()"))),
(PrimTypeTimestamp, ("asTimestamp", Some(".getValue()"))),
(PrimTypeParty, ("asParty", Some(".getValue()"))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ package object inner {
damlType match {
case TypePrim(PrimTypeBool, _) => ClassName.get(classOf[javaapi.data.Bool])
case TypePrim(PrimTypeInt64, _) => ClassName.get(classOf[javaapi.data.Int64])
case TypePrim(PrimTypeDecimal, _) => ClassName.get(classOf[javaapi.data.Decimal])
case TypePrim(PrimTypeDecimal, _) => ClassName.get(classOf[javaapi.data.Numeric])
case TypePrim(PrimTypeText, _) => ClassName.get(classOf[javaapi.data.Text])
case TypePrim(PrimTypeDate, _) => ClassName.get(classOf[javaapi.data.Date])
case TypePrim(PrimTypeTimestamp, _) => ClassName.get(classOf[javaapi.data.Timestamp])
Expand Down
Loading

0 comments on commit 20649cf

Please sign in to comment.