Commit c047fa1f authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 660ba040
......@@ -17,6 +17,7 @@ package zodb
import (
"context"
"fmt"
"reflect"
"sync"
"lab.nexedi.com/kirr/go123/mem"
......@@ -117,6 +118,7 @@ type classNewFunc func(base *Persistent) IPersistent
// {} class -> new(pyobj XXX)
var classTab = make(map[string]classNewFunc)
/*
// RegisterClass registers ZODB class to be transformed to Go instance
// created via classNew.
//
......@@ -126,7 +128,6 @@ func RegisterClass(class string, classNew classNewFunc) {
// XXX + register so that PyData decode handles class
}
// newGhost creates new ghost object corresponding to class and oid.
func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
base := &Persistent{class: class, jar: conn, oid: oid, serial: 0, state: GHOST}
......@@ -143,10 +144,62 @@ func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
base.instance = instance
return instance
}
*/
var class2Type = make(map[string]reflect.Type) // {} class -> type
var type2Class = make(map[reflect.Type]string) // {} type -> class
// RegisterClass registers ZODB class to correspond to Go type.
//
// *type must implement IPersistent. XXX and either Stateful or PyStateful
//
// Must be called from global init().
func RegisterClass(class string, typ reflect.Type) {
rIPersistent := reflect.TypeOf(IPersistent(nil))
if !typ.Implements(rIPersistent) {
panic(fmt.Sprintf("zodb: register class: %q does not implement IPersistent", typ))
}
// find out if typ implements PyStateful and, if yes, use PyPersistent as base
rPyStateful := reflect.TypeOf(PyStateful(nil))
if typ.Implements(rPyStateful) {
// XXX
}
// XXX check typ has IPersistent embedded
// XXX check *typ implements Stateful
class2Type[class] = typ
type2Class[typ] = class
}
// newGhost creates new ghost object corresponding to class and oid.
func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
// switch on class and transform e.g. "zodb.BTree.Bucket" -> btree.Bucket
var xpobj reflect.Value // *typ
typ := class2Type[class]
if typ == nil {
xpobj = reflect.ValueOf(&Broken{class: class})
} else {
xpobj = reflect.New(typ)
}
base := &Persistent{class: class, 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)
}
// Broken is used for classes that were not registered.
type Broken struct {
*Persistent
class string
state *mem.Buf
}
......
......@@ -102,9 +102,9 @@ type IPersistent interface {
//PState() ObjectState // in-RAM object state.
// Object must be stateful for persistency to work.
// XXX try to move out of IPersistent?
Stateful
// // Object must be stateful for persistency to work.
// // XXX try to move out of IPersistent?
// Stateful
}
// ObjectState describes state of in-RAM object.
......@@ -119,6 +119,7 @@ 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?
jar *Connection
......@@ -128,7 +129,8 @@ type Persistent struct {
mu sync.Mutex
state ObjectState
refcnt int32
instance IPersistent // Persistent should be the base for the instance
// 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
}
......
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