timestamps need to use unsigned in bson encoder/decoder

This commit is contained in:
Mike Dirolf 2010-06-04 12:50:22 -04:00
parent 68f425e9e4
commit cf46feb79e
5 changed files with 14 additions and 12 deletions

View File

@ -1497,11 +1497,10 @@ static PyObject* get_value(const char* buffer, int* position, int type,
}
case 17:
{
int time,
inc;
unsigned int time, inc;
memcpy(&inc, buffer + *position, 4);
memcpy(&time, buffer + *position + 4, 4);
value = PyObject_CallFunction(Timestamp, "ii", time, inc);
value = PyObject_CallFunction(Timestamp, "II", time, inc);
if (!value) {
return NULL;
}

View File

@ -50,9 +50,10 @@ except ImportError:
RE_TYPE = type(re.compile(""))
def _get_int(data, as_class=None):
def _get_int(data, as_class=None, unsigned=False):
format = unsigned and "I" or "i"
try:
value = struct.unpack("<i", data[:4])[0]
value = struct.unpack("<%s" % format, data[:4])[0]
except struct.error:
raise InvalidBSON()
@ -177,8 +178,8 @@ def _get_ref(data, as_class):
def _get_timestamp(data, as_class):
(inc, data) = _get_int(data)
(timestamp, data) = _get_int(data)
(inc, data) = _get_int(data, unsigned=True)
(timestamp, data) = _get_int(data, unsigned=True)
return (Timestamp(timestamp, inc), data)
@ -304,8 +305,8 @@ def _element_to_bson(key, value, check_keys):
value.microsecond / 1000)
return "\x09" + name + struct.pack("<q", millis)
if isinstance(value, Timestamp):
time = struct.pack("<i", value.time)
inc = struct.pack("<i", value.inc)
time = struct.pack("<I", value.time)
inc = struct.pack("<I", value.inc)
return "\x11" + name + inc + time
if value is None:
return "\x0A" + name

View File

@ -450,7 +450,7 @@ class Connection(object): # TODO support auth for pooling
finally:
if sock is not None:
sock.close()
if sock_error:
if sock_error or self.__host is None:
raise AutoReconnect("could not find master")
raise ConfigurationError("No master node in %r. You must specify "
"slave_okay to connect to "

View File

@ -56,7 +56,7 @@ class Timestamp(object):
if not 0 <= time < 2**32:
raise ValueError("time must be contained in [0, 2**32)")
if not 0 <= inc < 2**32:
raise ValueError("inc must be contained in [0, 2**32)")
raise ValueError("inc must be contained in [0, 2**32), not %r" % inc)
self.__time = time
self.__inc = inc

View File

@ -198,7 +198,9 @@ class TestDatabase(unittest.TestCase):
self.assertEqual(prev_error["nPrev"], 1)
del prev_error["nPrev"]
prev_error.pop("lastOp", None)
self.assertEqual(db.error(), prev_error)
error = db.error()
error.pop("lastOp", None)
self.assertEqual(error, prev_error)
db.test.find_one()
self.assertEqual(None, db.error())