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 {
var class2Type = make(map[string]reflect.Type) // {} class -> type
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.
//
// *type must implement IPersistent. XXX and either Stateful or PyStateful
......@@ -169,6 +176,8 @@ func RegisterClass(class string, typ reflect.Type) {
// XXX check typ has IPersistent embedded
// XXX check *typ implements Stateful
// XXX check if class was already registered
// XXX check class != ""
class2Type[class] = typ
type2Class[typ] = class
......@@ -186,14 +195,14 @@ func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
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
xobjBase := xobj.FieldByName("IPersistent")
xobjBase.Set(reflect.ValueOf(base))
obj := xpobj.Interface()
base.instance = obj.(interface{IPersistent; Stateful})
return obj.(IPersistent)
return base.instance
}
// Broken is used for classes that were not registered.
......@@ -258,8 +267,7 @@ func (conn *Connection) get(class string, oid Oid) (IPersistent, error) {
conn.objmu.Unlock()
if checkClass {
// XXX get obj class via reflection?
if cls := obj.zclass(); class != cls {
if cls := zclassOf(obj); class != cls {
return nil, &OpError{
URL: conn.stor.URL(),
Op: fmt.Sprintf("@%s: get", conn.at), // XXX abuse
......
......@@ -31,7 +31,7 @@ import (
//
// XXX safe to access from multiple goroutines simultaneously.
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.
POid() Oid // object ID in the database.
......@@ -119,8 +119,8 @@ const (
// Persistent is common base implementation for in-RAM representation of database objects.
type Persistent struct {
// XXX kill here; move -> Broken
class string // zodb class of this object. XXX try not to store and retrieve via reflect?
// // XXX kill here; move -> Broken
// class string // zodb class of this object. XXX try not to store and retrieve via reflect?
jar *Connection
oid Oid
......@@ -129,12 +129,11 @@ type Persistent struct {
mu sync.Mutex
state ObjectState
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
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) POid() Oid { return obj.oid }
func (obj *Persistent) PSerial() Tid { return obj.serial }
......
......@@ -77,13 +77,15 @@ func (pyobj *PyPersistent) SetState(state *mem.Buf) error {
}
class := pyclassPath(pyclass)
if class != pyobj.class {
obj := pyobj.pyinstance()
if objClass := zclassOf(obj); class != objClass {
// complain that pyclass changed
// (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
......
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