diff --git a/database.cc b/database.cc index 4b615975ad..e922a3f9cc 100644 --- a/database.cc +++ b/database.cc @@ -4,6 +4,7 @@ #include "database.hh" #include "net/byteorder.hh" +#include "db_clock.hh" bool less_unsigned(const bytes& v1, const bytes& v2) { @@ -128,12 +129,42 @@ struct boolean_type_impl : public simple_type_impl { } }; +struct date_type_impl : public abstract_type { + date_type_impl() : abstract_type("date") {} + virtual void serialize(const boost::any& value, std::ostream& out) override { + auto v = boost::any_cast(value); + int64_t i = v.time_since_epoch().count(); + i = net::hton(uint64_t(i)); + out.write(reinterpret_cast(&i), 8); + } + virtual object_opt deserialize(std::istream& in) override { + int64_t tmp; + auto n = in.rdbuf()->sgetn(reinterpret_cast(&tmp), 8); + if (n == 0) { + return {}; + } + if (n != 8) { + throw marshal_exception(); + } + tmp = net::ntoh(uint64_t(tmp)); + return boost::any(db_clock::time_point(db_clock::duration(tmp))); + } + virtual bool less(const bytes& b1, const bytes& b2) override { + // DateType has a bug where it compares the values as an unsigned type. + // Preserve this bug. + return default_less(b1, b2, [] (db_clock::time_point t1, db_clock::time_point t2) { + return uint64_t(t1.time_since_epoch().count() < t2.time_since_epoch().count()); + }); + } +}; + thread_local shared_ptr int_type(make_shared()); thread_local shared_ptr long_type(make_shared()); thread_local shared_ptr ascii_type(make_shared("ascii")); thread_local shared_ptr bytes_type(make_shared()); thread_local shared_ptr utf8_type(make_shared("utf8")); thread_local shared_ptr boolean_type(make_shared()); +thread_local shared_ptr date_type(make_shared()); partition::partition(column_family& cf) : rows(key_compare(cf.clustering_key_type)) {