Commit d695e2f1 authored by Kirill Smelkov's avatar Kirill Smelkov

go/zodb: Try to support bytes for OID

Since ZODB 5.4 OID is encoded as bytes, not str:

	https://github.com/zopefoundation/ZODB/commit/12ee41c473

Try to support both str and bytes on decoding, as we need to support all
ZODB versions.
parent 42118074
// Copyright (C) 2017 Nexedi SA and Contributors. // Copyright (C) 2017-2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your // it under the terms of the GNU General Public License version 3, or (at your
...@@ -23,7 +23,11 @@ ...@@ -23,7 +23,11 @@
package pickletools package pickletools
import ( import (
"encoding/binary"
"fmt"
"math/big" "math/big"
pickle "github.com/kisielk/og-rek"
) )
// Xint64 tries to convert unpickled value to int64. // Xint64 tries to convert unpickled value to int64.
...@@ -41,3 +45,34 @@ func Xint64(xv interface{}) (v int64, ok bool) { ...@@ -41,3 +45,34 @@ func Xint64(xv interface{}) (v int64, ok bool) {
return 0, false return 0, false
} }
// Xstrbytes verifies and extacts str|bytes from unpickled value.
func Xstrbytes(x interface{}) (string, error) {
var s string
switch x := x.(type) {
default:
return "", fmt.Errorf("expect str|bytes; got %T", x)
case string:
s = x
case pickle.Bytes:
s = string(x)
}
return s, nil
}
// Xstrbytes8 verifies and extracts [8](str|bytes) from unpickled value as big-endian u64.
func Xstrbytes8(x interface{}) (uint64, error) {
s, err := Xstrbytes(x)
if err != nil {
return 0, err
}
if len(s) != 8 {
return 0, fmt.Errorf("expect [8]bytes; got [%d]bytes", len(s))
}
return binary.BigEndian.Uint64([]byte(s)), nil
}
...@@ -22,11 +22,12 @@ package zodb ...@@ -22,11 +22,12 @@ package zodb
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"strings" "strings"
pickle "github.com/kisielk/og-rek" pickle "github.com/kisielk/og-rek"
"lab.nexedi.com/kirr/neo/go/zodb/internal/pickletools"
"lab.nexedi.com/kirr/go123/xerr" "lab.nexedi.com/kirr/go123/xerr"
) )
...@@ -232,20 +233,17 @@ func xpyclass(xklass interface{}) (_ pickle.Class, err error) { ...@@ -232,20 +233,17 @@ func xpyclass(xklass interface{}) (_ pickle.Class, err error) {
} }
// xoid verifies and extracts oid from unpickled value. // xoid verifies and extracts oid from unpickled value.
//
// TODO +zobdpickle.binary support
func xoid(x interface{}) (_ Oid, err error) { func xoid(x interface{}) (_ Oid, err error) {
defer xerr.Context(&err, "oid") defer xerr.Context(&err, "oid")
s, ok := x.(string) // ZODB >= 5.4 encodes oid as bytes; before - as str:
if !ok { // https://github.com/zopefoundation/ZODB/commit/12ee41c473
return InvalidOid, fmt.Errorf("expect str; got %T", x) v, err := pickletools.Xstrbytes8(x)
} if err != nil {
if len(s) != 8 { return InvalidOid, err
return InvalidOid, fmt.Errorf("expect [8]str; got [%d]str", len(s))
} }
return Oid(binary.BigEndian.Uint64([]byte(s))), nil return Oid(v), nil
} }
// pyclassPath returns full path for a python class. // pyclassPath returns full path for a python class.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment