示例#1
0
 def _hydrate_point(self, srid, *coordinates):
     """ Create a new instance of a Point subclass from a raw
     set of fields. The subclass chosen is determined by the
     given SRID; a ValueError will be raised if no such
     subclass can be found.
     """
     try:
         point_class, dim = Point.class_for_srid(srid)
     except KeyError:
         point = Point(coordinates)
         point.srid = srid
         return point
     else:
         if len(coordinates) != dim:
             raise ValueError("SRID %d requires %d coordinates (%d provided)" % (srid, dim, len(coordinates)))
         return point_class(coordinates)
示例#2
0
def test_4d_point():
    with raises(ValueError):
        _ = pack(Point((0, 0, 0, 0)), version=(2, 0))
示例#3
0
    def dehydrate(self, data, version=None):
        """ Dehydrate to PackStream.
        """
        from datetime import date, time, datetime, timedelta
        from neotime import Duration, Date, Time, DateTime
        from pytz import utc
        from py2neo.data.spatial import Point

        unix_epoch_date = Date(1970, 1, 1)

        if version is None:
            v = (1, 0)
        elif isinstance(version, tuple):
            v = version
        else:
            v = (version, 0)

        def dehydrate_object(x):
            t = type(x)
            if t in functions:
                f = functions[t]
                return f(x)
            elif x is None or x is True or x is False or isinstance(x, float) or isinstance(x, string_types):
                return x
            elif isinstance(x, integer_types):
                if x < INT64_MIN or x > INT64_MAX:
                    raise ValueError("Integers must be within the signed 64-bit range")
                return x
            elif isinstance(x, bytearray):
                return x
            elif isinstance(x, Mapping):
                d = {}
                for key in x:
                    if not isinstance(key, string_types):
                        raise TypeError("Dictionary keys must be strings")
                    d[key] = dehydrate_object(x[key])
                return d
            elif isinstance(x, Sequence):
                return list(map(dehydrate_object, x))
            else:
                raise TypeError("PackStream parameters of type %s are not supported" % type(x).__name__)

        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_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 neotime.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 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
                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 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_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 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)

        functions = {}  # graph types cannot be used as parameters
        if v >= (2, 0):
            functions.update({
                Date: dehydrate_date,
                date: dehydrate_date,
                Time: dehydrate_time,
                time: dehydrate_time,
                DateTime: dehydrate_datetime,
                datetime: dehydrate_datetime,
                Duration: dehydrate_duration,
                timedelta: dehydrate_timedelta,
                Point: dehydrate_point,
            })
            functions.update({
                cls: dehydrate_point
                for cls in Point.__subclasses__()
            })

        return dehydrate_object(data)