Commit c047fa1f authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 660ba040
...@@ -17,6 +17,7 @@ package zodb ...@@ -17,6 +17,7 @@ package zodb
import ( import (
"context" "context"
"fmt" "fmt"
"reflect"
"sync" "sync"
"lab.nexedi.com/kirr/go123/mem" "lab.nexedi.com/kirr/go123/mem"
...@@ -117,6 +118,7 @@ type classNewFunc func(base *Persistent) IPersistent ...@@ -117,6 +118,7 @@ type classNewFunc func(base *Persistent) IPersistent
// {} class -> new(pyobj XXX) // {} class -> new(pyobj XXX)
var classTab = make(map[string]classNewFunc) var classTab = make(map[string]classNewFunc)
/*
// RegisterClass registers ZODB class to be transformed to Go instance // RegisterClass registers ZODB class to be transformed to Go instance
// created via classNew. // created via classNew.
// //
...@@ -126,7 +128,6 @@ func RegisterClass(class string, classNew classNewFunc) { ...@@ -126,7 +128,6 @@ func RegisterClass(class string, classNew classNewFunc) {
// XXX + register so that PyData decode handles class // XXX + register so that PyData decode handles class
} }
// newGhost creates new ghost object corresponding to class and oid. // newGhost creates new ghost object corresponding to class and oid.
func (conn *Connection) newGhost(class string, oid Oid) IPersistent { func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
base := &Persistent{class: class, jar: conn, oid: oid, serial: 0, state: GHOST} 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 { ...@@ -143,10 +144,62 @@ func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
base.instance = instance base.instance = instance
return 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. // Broken is used for classes that were not registered.
type Broken struct { type Broken struct {
*Persistent *Persistent
class string
state *mem.Buf state *mem.Buf
} }
......
...@@ -102,9 +102,9 @@ type IPersistent interface { ...@@ -102,9 +102,9 @@ type IPersistent interface {
//PState() ObjectState // in-RAM object state. //PState() ObjectState // in-RAM object state.
// Object must be stateful for persistency to work. // // Object must be stateful for persistency to work.
// XXX try to move out of IPersistent? // // XXX try to move out of IPersistent?
Stateful // Stateful
} }
// ObjectState describes state of in-RAM object. // ObjectState describes state of in-RAM object.
...@@ -119,6 +119,7 @@ const ( ...@@ -119,6 +119,7 @@ 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
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
...@@ -128,7 +129,8 @@ type Persistent struct { ...@@ -128,7 +129,8 @@ 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 // 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 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