Commit 43b13845 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent e7a6e2f3
...@@ -40,55 +40,28 @@ import ( ...@@ -40,55 +40,28 @@ import (
// for format description. // for format description.
type PyData []byte type PyData []byte
// xoid verifies and extracts oid from unpickled value. // ClassName returns fully-qualified python class name used for object type.
//
// XXX +zobdpickle.binary support
// XXX -> shared place
func xoid(x interface{}) (Oid, error) {
s, ok := x.(string)
if !ok {
return InvalidOid, fmt.Errorf("xoid: expect str; got %T", x)
}
if len(s) != 8 {
return InvalidOid, fmt.Errorf("xoid: expect [8]str; got [%d]str", len(s))
}
return Oid(binary.BigEndian.Uint64([]byte(s))), nil
}
// loadref loads persistent references resolving them through jar.
//
// https://github.com/zopefoundation/ZODB/blob/a89485c1/src/ZODB/serialize.py#L80
// //
// XXX place? // The format is "module.class".
func (jar *Connection) loadref(ref pickle.Ref) (_ interface{}, err error) { // If pickle decoding fails - "?.?" is returned.
defer xerr.Context(&err, "loadref") func (d PyData) ClassName() string {
// see ObjectReader.getClassName & get_pickle_metadata in zodb/py
// TODO add support for ref formats besides (oid, class) p := pickle.NewDecoder(bytes.NewReader([]byte(d)))
xklass, err := p.Decode()
t, ok := ref.Pid.(pickle.Tuple)
if !ok {
return nil, fmt.Errorf("expect (); got %T", ref.Pid)
}
if len(t) != 2 {
return nil, fmt.Errorf("expect (oid, class); got [%d]()", len(t))
}
oid, err := xoid(t[0])
if err != nil { if err != nil {
return nil, err // XXX err ctx return "?.?"
} }
pyclass, err := normPyClass(t[1]) klass, err := normPyClass(xklass)
if err != nil { if err != nil {
return nil, err // XXX err ctx return "?.?"
} }
class := pyclassPath(pyclass) return pyclassPath(klass)
return jar.get(class, oid)
} }
// TODO PyData.referencesf
// decode decodes raw ZODB python data into Python class and state. // decode decodes raw ZODB python data into Python class and state.
// //
// jar is used to resolve persistent references. // jar is used to resolve persistent references.
...@@ -118,27 +91,39 @@ func (d PyData) decode(jar *Connection) (pyclass pickle.Class, pystate interface ...@@ -118,27 +91,39 @@ func (d PyData) decode(jar *Connection) (pyclass pickle.Class, pystate interface
return klass, state, nil return klass, state, nil
} }
// loadref loads persistent references resolving them through jar.
// ClassName returns fully-qualified python class name used for object type.
// //
// The format is "module.class". // https://github.com/zopefoundation/ZODB/blob/a89485c1/src/ZODB/serialize.py#L80
// If pickle decoding fails - "?.?" is returned. func (jar *Connection) loadref(ref pickle.Ref) (_ interface{}, err error) {
func (d PyData) ClassName() string { defer xerr.Context(&err, "loadref")
// see ObjectReader.getClassName & get_pickle_metadata in zodb/py
p := pickle.NewDecoder(bytes.NewReader([]byte(d))) // TODO add support for ref formats besides (oid, class)
xklass, err := p.Decode()
t, ok := ref.Pid.(pickle.Tuple)
if !ok {
return nil, fmt.Errorf("expect (); got %T", ref.Pid)
}
if len(t) != 2 {
return nil, fmt.Errorf("expect (oid, class); got [%d]()", len(t))
}
oid, err := xoid(t[0])
if err != nil { if err != nil {
return "?.?" return nil, err // XXX err ctx
} }
klass, err := normPyClass(xklass) pyclass, err := normPyClass(t[1])
if err != nil { if err != nil {
return "?.?" return nil, err // XXX err ctx
} }
return pyclassPath(klass) class := pyclassPath(pyclass)
return jar.get(class, oid)
} }
var errInvalidPyClass = errors.New("invalid py class description") var errInvalidPyClass = errors.New("invalid py class description")
// normPyClass normalizes py class that has just been decoded from a serialized // normPyClass normalizes py class that has just been decoded from a serialized
...@@ -178,3 +163,26 @@ func normPyClass(xklass interface{}) (pickle.Class, error) { ...@@ -178,3 +163,26 @@ func normPyClass(xklass interface{}) (pickle.Class, error) {
return pickle.Class{}, errInvalidPyClass return pickle.Class{}, errInvalidPyClass
} }
// pyclassPath returns full path for a python class.
//
// for example class "ABC" in module "wendelin.lib" has its full path as "wendelin.lib.ABC".
func pyclassPath(pyclass pickle.Class) string {
return pyclass.Module + "." + pyclass.Name
}
// xoid verifies and extracts oid from unpickled value.
//
// XXX +zobdpickle.binary support
// XXX -> shared place
func xoid(x interface{}) (Oid, error) {
s, ok := x.(string)
if !ok {
return InvalidOid, fmt.Errorf("xoid: expect str; got %T", x)
}
if len(s) != 8 {
return InvalidOid, fmt.Errorf("xoid: expect [8]str; got [%d]str", len(s))
}
return Oid(binary.BigEndian.Uint64([]byte(s))), nil
}
...@@ -20,14 +20,10 @@ ...@@ -20,14 +20,10 @@
package zodb package zodb
// Support for python objects/data in ZODB. // Support for python objects/data in ZODB.
// XXX + PyData.referencesf ?
import ( import (
"context" "context"
"lab.nexedi.com/kirr/go123/mem" "lab.nexedi.com/kirr/go123/mem"
pickle "github.com/kisielk/og-rek"
) )
// PyStateful is the interface describing in-RAM object whose data state can be // PyStateful is the interface describing in-RAM object whose data state can be
...@@ -72,15 +68,6 @@ func pySetState(obj PyStateful, objClass string, state *mem.Buf, jar *Connection ...@@ -72,15 +68,6 @@ func pySetState(obj PyStateful, objClass string, state *mem.Buf, jar *Connection
// ----------------------------------------
// pyclassPath returns full path for a python class.
//
// for example class "ABC" in module "wendelin.lib" has its full path as "wendelin.lib.ABC".
func pyclassPath(pyclass pickle.Class) string {
return pyclass.Module + "." + pyclass.Name
}
// loadpy loads object specified by oid and decodes it as a ZODB Python object. // loadpy loads object specified by oid and decodes it as a ZODB Python object.
// //
// loadpy does not create any in-RAM object associated with Connection. // loadpy does not create any in-RAM object associated with Connection.
......
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