Commit 1cdfff35 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 5b4637e2
...@@ -186,26 +186,27 @@ func (e *wrongClassError) Error() string { ...@@ -186,26 +186,27 @@ func (e *wrongClassError) Error() string {
// //
// Use-case: in ZODB references are (pyclass, oid), so new ghost is created // Use-case: in ZODB references are (pyclass, oid), so new ghost is created
// without further loading anything. // without further loading anything.
func (conn *Connection) get(class string, oid Oid) (IPyPersistent, error) { func (conn *Connection) get(class string, oid Oid) (IPersistent, error) {
conn.objmu.Lock() // XXX -> rlock conn.objmu.Lock() // XXX -> rlock
wobj := conn.objtab[oid] wobj := conn.objtab[oid]
var pyobj IPyPersistent var obj IPersistent
checkClass := false checkClass := false
if wobj != nil { if wobj != nil {
if xobj := wobj.Get(); xobj != nil { if xobj := wobj.Get(); xobj != nil {
pyobj = xobj.(IPyPersistent) obj = xobj.(IPersistent)
} }
} }
if pyobj == nil { if obj == nil {
pyobj = conn.newGhost(class, oid) obj = conn.newGhost(class, oid)
conn.objtab[oid] = weak.NewRef(pyobj) conn.objtab[oid] = weak.NewRef(obj)
} else { } else {
checkClass = true checkClass = true
} }
conn.objmu.Unlock() conn.objmu.Unlock()
if checkClass { if checkClass {
if cls := pyobj.PyClass(); class != cls { // XXX get obj class via reflection?
if cls := obj.PyClass(); 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
...@@ -215,10 +216,53 @@ func (conn *Connection) get(class string, oid Oid) (IPyPersistent, error) { ...@@ -215,10 +216,53 @@ func (conn *Connection) get(class string, oid Oid) (IPyPersistent, error) {
} }
} }
return pyobj, nil return obj, nil
} }
// Get returns in-RAM object corresponding to specified ZODB object according to current database view.
//
// If there is already in-RAM object that corresponds to oid, that in-RAM object is returned.
// Otherwise new in-RAM object is created and filled with object's class loaded from the database.
//
// The scope of the object returned is the Connection. XXX ok?
//
// The object's data is not necessarily loaded after Get returns. Use
// PActivate to make sure the object is fully loaded.
func (conn *Connection) Get(ctx context.Context, oid Oid) (IPersistent, error) {
conn.objmu.Lock() // XXX -> rlock
wobj := conn.objtab[oid]
var xobj interface{}
if wobj != nil {
xobj = wobj.Get()
}
conn.objmu.Unlock()
// object was already there in objtab.
if xobj != nil {
return xobj.(IPersistent), nil
}
// object is not there in objtab - raw load it, get its class -> get(pyclass, oid)
// XXX py hardcoded
pyclass, pystate, serial, err := conn.loadpy(ctx, oid)
if err != nil {
return nil, err // XXX errctx
}
obj, err := conn.get(pyclass.Module + "." + pyclass.Name, oid)
if err != nil {
return nil, err
}
// XXX we are dropping just loaded pystate. Usually Get should be used
// to only load root object, so maybe that is ok.
//
// TODO -> use (pystate, serial) to activate.
_, _ = pystate, serial
return obj, nil
}
......
...@@ -144,48 +144,6 @@ func (d *dummyPyInstance) PySetState(pystate interface{}) error { ...@@ -144,48 +144,6 @@ func (d *dummyPyInstance) PySetState(pystate interface{}) error {
// ---------------------------------------- // ----------------------------------------
// Get returns in-RAM object corresponding to specified ZODB object according to current database view.
//
// If there is already in-RAM object that corresponds to oid, that in-RAM object is returned.
// Otherwise new in-RAM object is created and filled with object's class loaded from the database.
//
// The scope of the object returned is the Connection. XXX ok?
//
// The object's data is not necessarily loaded after Get returns. Use
// PActivate to make sure the object is fully loaded.
func (conn *Connection) Get(ctx context.Context, oid Oid) (IPyPersistent, error) {
conn.objmu.Lock() // XXX -> rlock
wobj := conn.objtab[oid]
var xobj interface{}
if wobj != nil {
xobj = wobj.Get()
}
conn.objmu.Unlock()
// object was already there in objtab.
if xobj != nil {
return xobj.(IPyPersistent), nil // XXX if just IPersistent ?
}
// object is not there in objtab - raw load it, get its class -> get(pyclass, oid)
pyclass, pystate, serial, err := conn.loadpy(ctx, oid)
if err != nil {
return nil, err // XXX errctx
}
obj, err := conn.get(pyclass, oid)
if err != nil {
return nil, err
}
// XXX we are dropping just loaded pystate. Usually Get should be used
// to only load root object, so maybe that is ok.
//
// TODO -> use (pystate, serial) to activate.
_, _ = pystate, serial
return obj, nil
}
// 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