Commit f5b30c35 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent c047fa1f
...@@ -149,6 +149,13 @@ func (conn *Connection) newGhost(class string, oid Oid) IPersistent { ...@@ -149,6 +149,13 @@ func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
var class2Type = make(map[string]reflect.Type) // {} class -> type var class2Type = make(map[string]reflect.Type) // {} class -> type
var type2Class = make(map[reflect.Type]string) // {} type -> class var type2Class = make(map[reflect.Type]string) // {} type -> class
// zclassOf returns ZODB class of a Go object.
//
// If ZODB class was not registered for obj's type, "" is returned.
func zclassOf(obj IPersistent) string {
return type2Class[reflect.TypeOf(obj)]
}
// RegisterClass registers ZODB class to correspond to Go type. // RegisterClass registers ZODB class to correspond to Go type.
// //
// *type must implement IPersistent. XXX and either Stateful or PyStateful // *type must implement IPersistent. XXX and either Stateful or PyStateful
...@@ -169,6 +176,8 @@ func RegisterClass(class string, typ reflect.Type) { ...@@ -169,6 +176,8 @@ func RegisterClass(class string, typ reflect.Type) {
// XXX check typ has IPersistent embedded // XXX check typ has IPersistent embedded
// XXX check *typ implements Stateful // XXX check *typ implements Stateful
// XXX check if class was already registered
// XXX check class != ""
class2Type[class] = typ class2Type[class] = typ
type2Class[typ] = class type2Class[typ] = class
...@@ -186,14 +195,14 @@ func (conn *Connection) newGhost(class string, oid Oid) IPersistent { ...@@ -186,14 +195,14 @@ func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
xpobj = reflect.New(typ) xpobj = reflect.New(typ)
} }
base := &Persistent{class: class, jar: conn, oid: oid, serial: 0, state: GHOST} base := &Persistent{jar: conn, oid: oid, serial: 0, state: GHOST}
xobj := xpobj.Elem() // typ xobj := xpobj.Elem() // typ
xobjBase := xobj.FieldByName("IPersistent") xobjBase := xobj.FieldByName("IPersistent")
xobjBase.Set(reflect.ValueOf(base)) xobjBase.Set(reflect.ValueOf(base))
obj := xpobj.Interface() obj := xpobj.Interface()
base.instance = obj.(interface{IPersistent; Stateful}) base.instance = obj.(interface{IPersistent; Stateful})
return obj.(IPersistent) return base.instance
} }
// Broken is used for classes that were not registered. // Broken is used for classes that were not registered.
...@@ -258,8 +267,7 @@ func (conn *Connection) get(class string, oid Oid) (IPersistent, error) { ...@@ -258,8 +267,7 @@ func (conn *Connection) get(class string, oid Oid) (IPersistent, error) {
conn.objmu.Unlock() conn.objmu.Unlock()
if checkClass { if checkClass {
// XXX get obj class via reflection? if cls := zclassOf(obj); class != cls {
if cls := obj.zclass(); class != cls {
return nil, &OpError{ return nil, &OpError{
URL: conn.stor.URL(), URL: conn.stor.URL(),
Op: fmt.Sprintf("@%s: get", conn.at), // XXX abuse Op: fmt.Sprintf("@%s: get", conn.at), // XXX abuse
......
...@@ -31,7 +31,7 @@ import ( ...@@ -31,7 +31,7 @@ import (
// //
// XXX safe to access from multiple goroutines simultaneously. // XXX safe to access from multiple goroutines simultaneously.
type IPersistent interface { type IPersistent interface {
zclass() string // ZODB class of this object. XXX remove from IPersistent? //zclass() string // ZODB class of this object. XXX remove from IPersistent?
PJar() *Connection // Connection this in-RAM object is part of. PJar() *Connection // Connection this in-RAM object is part of.
POid() Oid // object ID in the database. POid() Oid // object ID in the database.
...@@ -119,8 +119,8 @@ const ( ...@@ -119,8 +119,8 @@ const (
// Persistent is common base implementation for in-RAM representation of database objects. // Persistent is common base implementation for in-RAM representation of database objects.
type Persistent struct { type Persistent struct {
// XXX kill here; move -> Broken // // XXX kill here; move -> Broken
class string // zodb class of this object. XXX try not to store and retrieve via reflect? // class string // zodb class of this object. XXX try not to store and retrieve via reflect?
jar *Connection jar *Connection
oid Oid oid Oid
...@@ -129,12 +129,11 @@ type Persistent struct { ...@@ -129,12 +129,11 @@ type Persistent struct {
mu sync.Mutex mu sync.Mutex
state ObjectState state ObjectState
refcnt int32 refcnt int32
// instance IPersistent // Persistent should be the base for the instance XXX -> Stateful
instance interface{IPersistent; Stateful} // Persistent should be the base for the instance instance interface{IPersistent; Stateful} // Persistent should be the base for the instance
loading *loadState loading *loadState
} }
func (obj *Persistent) zclass() string { return obj.class } //func (obj *Persistent) zclass() string { return obj.class }
func (obj *Persistent) PJar() *Connection { return obj.jar } func (obj *Persistent) PJar() *Connection { return obj.jar }
func (obj *Persistent) POid() Oid { return obj.oid } func (obj *Persistent) POid() Oid { return obj.oid }
func (obj *Persistent) PSerial() Tid { return obj.serial } func (obj *Persistent) PSerial() Tid { return obj.serial }
......
...@@ -77,13 +77,15 @@ func (pyobj *PyPersistent) SetState(state *mem.Buf) error { ...@@ -77,13 +77,15 @@ func (pyobj *PyPersistent) SetState(state *mem.Buf) error {
} }
class := pyclassPath(pyclass) class := pyclassPath(pyclass)
if class != pyobj.class { obj := pyobj.pyinstance()
if objClass := zclassOf(obj); class != objClass {
// complain that pyclass changed // complain that pyclass changed
// (both ref and object data use pyclass so it indeed can be different) // (both ref and object data use pyclass so it indeed can be different)
return &wrongClassError{want: pyobj.class, have: class} // XXX + err ctx return &wrongClassError{want: objClass, have: class} // XXX + err ctx
} }
return pyobj.pyinstance().PySetState(pystate) // XXX err ctx = ok? return obj.PySetState(pystate) // XXX err ctx = ok?
} }
// TODO PyPersistent.GetState // TODO PyPersistent.GetState
......
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