Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 37af5a0

Browse filesBrowse files
committed
feat(spanner): add spanner::Value support for TypeCode::INTERVAL (googleapis#15094)
1 parent dc9477d commit 37af5a0
Copy full SHA for 37af5a0

File tree

Expand file treeCollapse file tree

3 files changed

+86
-0
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+86
-0
lines changed

‎google/cloud/spanner/value.cc

Copy file name to clipboardExpand all lines: google/cloud/spanner/value.cc
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ std::ostream& StreamHelper(std::ostream& os, // NOLINT(misc-no-recursion)
158158
case google::spanner::v1::TypeCode::JSON:
159159
case google::spanner::v1::TypeCode::TIMESTAMP:
160160
case google::spanner::v1::TypeCode::NUMERIC:
161+
case google::spanner::v1::TypeCode::INTERVAL:
161162
case google::spanner::v1::TypeCode::UUID:
162163
return os << v.string_value();
163164

@@ -270,6 +271,10 @@ bool Value::TypeProtoIs(absl::CivilDay, google::spanner::v1::Type const& type) {
270271
return type.code() == google::spanner::v1::TypeCode::DATE;
271272
}
272273

274+
bool Value::TypeProtoIs(Interval, google::spanner::v1::Type const& type) {
275+
return type.code() == google::spanner::v1::TypeCode::INTERVAL;
276+
}
277+
273278
bool Value::TypeProtoIs(Uuid, google::spanner::v1::Type const& type) {
274279
return type.code() == google::spanner::v1::TypeCode::UUID;
275280
}
@@ -409,6 +414,12 @@ google::spanner::v1::Type Value::MakeTypeProto(absl::CivilDay) {
409414
return t;
410415
}
411416

417+
google::spanner::v1::Type Value::MakeTypeProto(Interval) {
418+
google::spanner::v1::Type t;
419+
t.set_code(google::spanner::v1::TypeCode::INTERVAL);
420+
return t;
421+
}
422+
412423
google::spanner::v1::Type Value::MakeTypeProto(Uuid) {
413424
google::spanner::v1::Type t;
414425
t.set_code(google::spanner::v1::TypeCode::UUID);
@@ -531,6 +542,12 @@ google::protobuf::Value Value::MakeValueProto(absl::CivilDay d) {
531542
return v;
532543
}
533544

545+
google::protobuf::Value Value::MakeValueProto(Interval intvl) {
546+
google::protobuf::Value v;
547+
v.set_string_value(std::string(intvl));
548+
return v;
549+
}
550+
534551
google::protobuf::Value Value::MakeValueProto(Uuid u) {
535552
google::protobuf::Value v;
536553
v.set_string_value(std::string(u));
@@ -728,6 +745,14 @@ StatusOr<absl::CivilDay> Value::GetValue(absl::CivilDay,
728745
s + ": Failed to match RFC3339 full-date", GCP_ERROR_INFO());
729746
}
730747

748+
StatusOr<Interval> Value::GetValue(Interval, google::protobuf::Value const& pv,
749+
google::spanner::v1::Type const&) {
750+
if (pv.kind_case() != google::protobuf::Value::kStringValue) {
751+
return Status(StatusCode::kUnknown, "missing Interval");
752+
}
753+
return MakeInterval(pv.string_value());
754+
}
755+
731756
StatusOr<Uuid> Value::GetValue(Uuid, google::protobuf::Value const& pv,
732757
google::spanner::v1::Type const&) {
733758
if (pv.kind_case() != google::protobuf::Value::kStringValue) {

‎google/cloud/spanner/value.h

Copy file name to clipboardExpand all lines: google/cloud/spanner/value.h
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "google/cloud/spanner/bytes.h"
1919
#include "google/cloud/spanner/date.h"
2020
#include "google/cloud/spanner/internal/tuple_utils.h"
21+
#include "google/cloud/spanner/interval.h"
2122
#include "google/cloud/spanner/json.h"
2223
#include "google/cloud/spanner/numeric.h"
2324
#include "google/cloud/spanner/oid.h"
@@ -78,6 +79,7 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
7879
* OID(PG) | `google::cloud::spanner::PgOid`
7980
* TIMESTAMP | `google::cloud::spanner::Timestamp`
8081
* DATE | `absl::CivilDay`
82+
* INTERVAL | `google::cloud::spanner::Interval`
8183
* UUID | `google::cloud::spanner::Uuid`
8284
* ENUM | `google::cloud::spanner::ProtoEnum<E>`
8385
* PROTO | `google::cloud::spanner::ProtoMessage<M>`
@@ -224,6 +226,7 @@ class Value {
224226
explicit Value(absl::CivilDay v)
225227
: Value(PrivateConstructor{}, std::move(v)) {}
226228
/// @copydoc Value(bool)
229+
explicit Value(Interval v) : Value(PrivateConstructor{}, std::move(v)) {}
227230
explicit Value(Uuid v) : Value(PrivateConstructor{}, std::move(v)) {}
228231
/// @copydoc Value(bool)
229232
template <typename E>
@@ -391,6 +394,7 @@ class Value {
391394
static bool TypeProtoIs(Timestamp, google::spanner::v1::Type const&);
392395
static bool TypeProtoIs(CommitTimestamp, google::spanner::v1::Type const&);
393396
static bool TypeProtoIs(absl::CivilDay, google::spanner::v1::Type const&);
397+
static bool TypeProtoIs(Interval, google::spanner::v1::Type const&);
394398
static bool TypeProtoIs(Uuid, google::spanner::v1::Type const&);
395399
static bool TypeProtoIs(std::string const&, google::spanner::v1::Type const&);
396400
static bool TypeProtoIs(Bytes const&, google::spanner::v1::Type const&);
@@ -465,6 +469,7 @@ class Value {
465469
static google::spanner::v1::Type MakeTypeProto(Timestamp);
466470
static google::spanner::v1::Type MakeTypeProto(CommitTimestamp);
467471
static google::spanner::v1::Type MakeTypeProto(absl::CivilDay);
472+
static google::spanner::v1::Type MakeTypeProto(Interval);
468473
static google::spanner::v1::Type MakeTypeProto(Uuid);
469474
template <typename E>
470475
static google::spanner::v1::Type MakeTypeProto(ProtoEnum<E>) {
@@ -545,6 +550,7 @@ class Value {
545550
static google::protobuf::Value MakeValueProto(Timestamp ts);
546551
static google::protobuf::Value MakeValueProto(CommitTimestamp ts);
547552
static google::protobuf::Value MakeValueProto(absl::CivilDay d);
553+
static google::protobuf::Value MakeValueProto(Interval intvl);
548554
static google::protobuf::Value MakeValueProto(Uuid u);
549555
template <typename E>
550556
static google::protobuf::Value MakeValueProto(ProtoEnum<E> e) {
@@ -636,6 +642,8 @@ class Value {
636642
static StatusOr<absl::CivilDay> GetValue(absl::CivilDay,
637643
google::protobuf::Value const&,
638644
google::spanner::v1::Type const&);
645+
static StatusOr<Interval> GetValue(Interval, google::protobuf::Value const&,
646+
google::spanner::v1::Type const&);
639647
static StatusOr<Uuid> GetValue(Uuid, google::protobuf::Value const&,
640648
google::spanner::v1::Type const&);
641649
template <typename E>

‎google/cloud/spanner/value_test.cc

Copy file name to clipboardExpand all lines: google/cloud/spanner/value_test.cc
+53Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,15 @@ TEST(Value, BasicSemantics) {
264264
v.resize(10);
265265
TestBasicSemantics(v);
266266

267+
for (auto x : {Interval(), MakeInterval("P1Y1M1D").value()}) {
268+
SCOPED_TRACE("Testing: google::cloud::spanner::Interval " + std::string{x});
269+
TestBasicSemantics(x);
270+
TestBasicSemantics(std::vector<Interval>(5, x));
271+
std::vector<absl::optional<Interval>> v(5, x);
272+
v.resize(10);
273+
TestBasicSemantics(v);
274+
}
275+
267276
for (auto x : {Uuid()}) {
268277
SCOPED_TRACE("Testing: google::cloud::spanner::Uuid " + std::string{x});
269278
TestBasicSemantics(x);
@@ -931,6 +940,24 @@ TEST(Value, ProtoConversionDate) {
931940
}
932941
}
933942

943+
TEST(Value, ProtoConversionInterval) {
944+
for (auto const& x : std::vector<Interval>{
945+
MakeInterval("-P178000Y").value(),
946+
MakeInterval("-P1Y2M3DT4H5M6.789S").value(),
947+
MakeInterval("-PT0.000001S").value(),
948+
Interval(),
949+
MakeInterval("PT0.000001S").value(),
950+
MakeInterval("P1Y2M3DT4H5M6.789S").value(),
951+
MakeInterval("P178000Y").value(),
952+
}) {
953+
Value const v(x);
954+
auto const p = spanner_internal::ToProto(v);
955+
EXPECT_EQ(v, spanner_internal::FromProto(p.first, p.second));
956+
EXPECT_EQ(google::spanner::v1::TypeCode::INTERVAL, p.first.code());
957+
EXPECT_EQ(std::string{x}, p.second.string_value());
958+
}
959+
}
960+
934961
TEST(Value, ProtoConversionUuid) {
935962
for (auto const& x : std::vector<Uuid>{
936963
Uuid(),
@@ -1274,6 +1301,24 @@ TEST(Value, GetBadDate) {
12741301
EXPECT_THAT(v.get<absl::CivilDay>(), Not(IsOk()));
12751302
}
12761303

1304+
TEST(Value, GetBadInterval) {
1305+
Value v(Interval{});
1306+
ClearProtoKind(v);
1307+
EXPECT_THAT(v.get<Interval>(), Not(IsOk()));
1308+
1309+
SetProtoKind(v, google::protobuf::NULL_VALUE);
1310+
EXPECT_THAT(v.get<Interval>(), Not(IsOk()));
1311+
1312+
SetProtoKind(v, true);
1313+
EXPECT_THAT(v.get<Interval>(), Not(IsOk()));
1314+
1315+
SetProtoKind(v, 0.0);
1316+
EXPECT_THAT(v.get<Interval>(), Not(IsOk()));
1317+
1318+
SetProtoKind(v, "blah");
1319+
EXPECT_THAT(v.get<Interval>(), Not(IsOk()));
1320+
}
1321+
12771322
TEST(Value, GetBadUuid) {
12781323
Value v(Uuid{});
12791324
ClearProtoKind(v);
@@ -1470,6 +1515,7 @@ TEST(Value, OutputStream) {
14701515
{Value(PgOid(1234567890)), "1234567890", normal},
14711516
{Value(absl::CivilDay()), "1970-01-01", normal},
14721517
{Value(Timestamp()), "1970-01-01T00:00:00Z", normal},
1518+
{Value(Interval()), "P0D", normal},
14731519
{Value(Uuid()), "00000000-0000-0000-0000-000000000000", normal},
14741520
{Value(ProtoEnum<testing::Genre>(testing::Genre::POP)),
14751521
"google.cloud.spanner.testing.POP", normal},
@@ -1504,6 +1550,7 @@ TEST(Value, OutputStream) {
15041550
{MakeNullValue<PgOid>(), "NULL", normal},
15051551
{MakeNullValue<absl::CivilDay>(), "NULL", normal},
15061552
{MakeNullValue<Timestamp>(), "NULL", normal},
1553+
{MakeNullValue<Interval>(), "NULL", normal},
15071554
{MakeNullValue<Uuid>(), "NULL", normal},
15081555
{MakeNullValue<ProtoEnum<testing::Genre>>(), "NULL", normal},
15091556
{MakeNullValue<ProtoMessage<testing::SingerInfo>>(), "NULL", normal},
@@ -1525,6 +1572,7 @@ TEST(Value, OutputStream) {
15251572
{Value(std::vector<absl::CivilDay>{2}), "[1970-01-01, 1970-01-01]",
15261573
normal},
15271574
{Value(std::vector<Timestamp>{1}), "[1970-01-01T00:00:00Z]", normal},
1575+
{Value(std::vector<Interval>{1}), "[P0D]", normal},
15281576
{Value(std::vector<Uuid>{1}), "[00000000-0000-0000-0000-000000000000]",
15291577
normal},
15301578
{Value(std::vector<ProtoEnum<testing::Genre>>{testing::JAZZ,
@@ -1552,6 +1600,7 @@ TEST(Value, OutputStream) {
15521600
{MakeNullValue<std::vector<Numeric>>(), "NULL", normal},
15531601
{MakeNullValue<std::vector<absl::CivilDay>>(), "NULL", normal},
15541602
{MakeNullValue<std::vector<Timestamp>>(), "NULL", normal},
1603+
{MakeNullValue<std::vector<Interval>>(), "NULL", normal},
15551604
{MakeNullValue<std::vector<Uuid>>(), "NULL", normal},
15561605
{MakeNullValue<std::vector<ProtoEnum<testing::Genre>>>(), "NULL", normal},
15571606
{MakeNullValue<std::vector<ProtoMessage<testing::SingerInfo>>>(), "NULL",
@@ -1703,6 +1752,10 @@ TEST(Value, OutputStreamMatchesT) {
17031752
StreamMatchesValueStream(Timestamp());
17041753
StreamMatchesValueStream(MakeTimestamp(MakeTime(1, 1)).value());
17051754

1755+
// Interval
1756+
StreamMatchesValueStream(Interval());
1757+
StreamMatchesValueStream(MakeInterval("P1Y2M3DT4H5M6.789S").value());
1758+
17061759
// Uuid
17071760
StreamMatchesValueStream(Uuid());
17081761
StreamMatchesValueStream(

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.