def dehydrate_datetime(value): """ Dehydrator for `datetime` values. :param value: :type value: datetime :return: """ def seconds_and_nanoseconds(dt): if isinstance(dt, datetime): dt = DateTime.from_native(dt) zone_epoch = DateTime(1970, 1, 1, tzinfo=dt.tzinfo) t = dt.to_clock_time() - zone_epoch.to_clock_time() return t.seconds, t.nanoseconds tz = value.tzinfo if tz is None: # without time zone from pytz import utc value = utc.localize(value) seconds, nanoseconds = seconds_and_nanoseconds(value) return Structure(b"d", seconds, nanoseconds) elif hasattr(tz, "zone") and tz.zone: # with named time zone seconds, nanoseconds = seconds_and_nanoseconds(value) return Structure(b"f", seconds, nanoseconds, tz.zone) else: # with time offset seconds, nanoseconds = seconds_and_nanoseconds(value) return Structure(b"F", seconds, nanoseconds, tz.utcoffset(value).seconds)
def test_can_hydrate_node_structure(self): struct = Structure(3, b'N') struct.append("node/123") struct.append(["Person"]) struct.append({"name": "Alice"}) alice = hydrated(struct) assert alice.identity == "node/123" assert alice.labels == {"Person"} assert set(alice.keys()) == {"name"} assert alice.get("name") == "Alice"
def test_can_hydrate_in_dict(self): struct = Structure(3, b'N') struct.append("node/123") struct.append(["Person"]) struct.append({"name": "Alice"}) alice_in_dict = hydrated({"foo": struct}) assert isinstance(alice_in_dict, dict) alice = alice_in_dict["foo"] assert alice.identity == "node/123" assert alice.labels == {"Person"} assert set(alice.keys()) == {"name"} assert alice.get("name") == "Alice"
def dehydrate_point(value): """ Dehydrator for Point data. :param value: :type value: Point :return: """ dim = len(value) if dim == 2: return Structure(b"X", value.srid, *value) elif dim == 3: return Structure(b"Y", value.srid, *value) else: raise ValueError("Cannot dehydrate Point with %d dimensions" % dim)
def test_can_hydrate_node_structure(self): struct = Structure(b'N', 123, ["Person"], {"name": "Alice"}) alice, = self.hydrant.hydrate([struct]) self.assertEqual(alice.id, 123) self.assertEqual(alice.labels, {"Person"}) self.assertEqual(set(alice.keys()), {"name"}) self.assertEqual(alice.get("name"), "Alice")
def test_hydrating_unknown_structure_returns_same(): hydrant = DataHydrator() struct = Structure(b'?', "foo") mystery, = hydrant.hydrate([struct]) assert mystery == struct
def dehydrate_date(value): """ Dehydrator for `date` values. :param value: :type value: Date :return: """ return Structure(b"D", value.toordinal() - UNIX_EPOCH_DATE.toordinal())
def dehydrate_duration(value): """ Dehydrator for `duration` values. :param value: :type value: Duration :return: """ return Structure(b"E", value.months, value.days, value.seconds, int(1000000000 * value.subseconds))
def dehydrate_date(value): """ Dehydrator for `date` values. :param value: :type value: Date :return: """ return Structure(b"D", value.toordinal() - get_date_unix_epoch().toordinal())
def test_can_hydrate_node_structure(self): struct = Structure(3, b'N') struct.append(123) struct.append(["Person"]) struct.append({"name": "Alice"}) alice, = self.hydrant.hydrate([struct]) assert alice.id == 123 assert alice.labels == {"Person"} assert set(alice.keys()) == {"name"} assert alice.get("name") == "Alice"
def test_can_hydrate_date_time_structure(self): struct = Structure(b'd', 1539344261, 474716862) dt, = self.hydrant.hydrate([struct]) self.assertEqual(dt.year, 2018) self.assertEqual(dt.month, 10) self.assertEqual(dt.day, 12) self.assertEqual(dt.hour, 11) self.assertEqual(dt.minute, 37) self.assertEqual(dt.second, 41.474716862)
def test_can_hydrate_in_dict(self): struct = Structure(b'N', 123, ["Person"], {"name": "Alice"}) alice_in_dict, = self.hydrant.hydrate([{"foo": struct}]) self.assertIsInstance(alice_in_dict, dict) alice = alice_in_dict["foo"] self.assertEqual(alice.id, 123) self.assertEqual(alice.labels, {"Person"}) self.assertEqual(set(alice.keys()), {"name"}) self.assertEqual(alice.get("name"), "Alice")
def dehydrate_time(value): """ Dehydrator for `time` values. :param value: :type value: Time :return: """ if isinstance(value, Time): nanoseconds = int(value.ticks * 1000000000) elif isinstance(value, time): nanoseconds = (3600000000000 * value.hour + 60000000000 * value.minute + 1000000000 * value.second + 1000 * value.microsecond) else: raise TypeError("Value must be a neo4j.time.Time or a datetime.time") if value.tzinfo: return Structure(b"T", nanoseconds, value.tzinfo.utcoffset(value).seconds) else: return Structure(b"t", nanoseconds)
def test_can_hydrate_in_list(self): struct = Structure(b'N', 123, ["Person"], {"name": "Alice"}) alice_in_list, = self.hydrant.hydrate([[struct]]) self.assertIsInstance(alice_in_list, list) alice, = alice_in_list self.assertEqual(alice.id, 123) self.assertEqual(alice.labels, {"Person"}) self.assertEqual(set(alice.keys()), {"name"}) self.assertEqual(alice.get("name"), "Alice")
def test_can_hydrate_node_structure(): hydrant = DataHydrator() struct = Structure(b'N', 123, ["Person"], {"name": "Alice"}) alice, = hydrant.hydrate([struct]) assert alice.id == 123 assert alice.labels == {"Person"} assert set(alice.keys()) == {"name"} assert alice.get("name") == "Alice"
def test_can_hydrate_in_list(self): struct = Structure(3, b'N') struct.append(123) struct.append(["Person"]) struct.append({"name": "Alice"}) alice_in_list, = self.hydrant.hydrate([[struct]]) assert isinstance(alice_in_list, list) alice, = alice_in_list assert alice.id == 123 assert alice.labels == {"Person"} assert set(alice.keys()) == {"name"} assert alice.get("name") == "Alice"
def test_can_hydrate_in_dict(self): struct = Structure(3, b'N') struct.append(123) struct.append(["Person"]) struct.append({"name": "Alice"}) alice_in_dict, = self.hydrant.hydrate([{"foo": struct}]) assert isinstance(alice_in_dict, dict) alice = alice_in_dict["foo"] assert alice.id == 123 assert alice.labels == {"Person"} assert set(alice.keys()) == {"name"} assert alice.get("name") == "Alice"
def dehydrate_timedelta(value): """ Dehydrator for `timedelta` values. :param value: :type value: timedelta :return: """ months = 0 days = value.days seconds = value.seconds nanoseconds = 1000 * value.microseconds return Structure(b"E", months, days, seconds, nanoseconds)
def test_can_hydrate_in_list(): hydrant = DataHydrator() struct = Structure(b'N', 123, ["Person"], {"name": "Alice"}) alice_in_list, = hydrant.hydrate([[struct]]) assert isinstance(alice_in_list, list) alice, = alice_in_list assert alice.id == 123 assert alice.labels == {"Person"} assert set(alice.keys()) == {"name"} assert alice.get("name") == "Alice"
def test_can_hydrate_in_dict(): hydrant = DataHydrator() struct = Structure(b'N', 123, ["Person"], {"name": "Alice"}) alice_in_dict, = hydrant.hydrate([{"foo": struct}]) assert isinstance(alice_in_dict, dict) alice = alice_in_dict["foo"] assert alice.id == 123 assert alice.labels == {"Person"} assert set(alice.keys()) == {"name"} assert alice.get("name") == "Alice"
def write_reset(self): log.debug("[#%04X] C: RESET", self.connection_id) return self._write(Structure(b"\x0F"))
def write_run(self, cypher, parameters, extras): parameters = dict(parameters or {}) extras = dict(extras or {}) log.debug("[#%04X] C: RUN %r %r %r", self.connection_id, cypher, parameters, extras) return self._write(Structure(b"\x10", cypher, parameters, extras))
def write_discard_all(self): log.debug("[#%04X] C: DISCARD_ALL", self.connection_id) return self._write(Structure(b"\x2F"))
def write_pull_all(self): log.debug("[#%04X] C: PULL_ALL", self.connection_id) return self._write(Structure(b"\x3F"))
def write_commit(self): log.debug("[#%04X] C: COMMIT", self.connection_id) return self._write(Structure(b"\x12"))
def test_hydrating_unknown_structure_returns_same(self): struct = Structure(b'?', "foo") mystery, = self.hydrant.hydrate([struct]) self.assertEqual(mystery, struct)
def write_rollback(self): log.debug("[#%04X] C: ROLLBACK", self.connection_id) return self._write(Structure(b"\x13"))
def test_struct_size_overflow(self): with raises(OverflowError): fields = [1] * 16 self.packb(Structure(b"X", *fields))
def test_tiny_structs(self): for size in range(0x10): fields = [1] * size data_in = Structure(b"A", *fields) data_out = bytearray([0xB0 + size, 0x41] + fields) self.assert_packable(data_in, bytes(data_out))
def test_hydrating_unknown_structure_returns_same(self): struct = Structure(1, b'X') struct.append("foo") mystery = hydrated(struct) assert mystery == struct
def write_begin(self, extras): log.debug("[#%04X] C: BEGIN %r", self.connection_id, extras) return self._write(Structure(b"\x11", extras))
def test_empty_struct(self): self.assert_packable(Structure(b"X"), b"\xB0X")
def test_illegal_signature(self): with self.assertRaises(ValueError): self.assert_packable(Structure(b"XXX"), b"\xB0XXX")