Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
neoppod
Commits
922b606d
Commit
922b606d
authored
Jul 27, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
94e71512
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
31 additions
and
20 deletions
+31
-20
go/zodb/connection.go
go/zodb/connection.go
+13
-13
go/zodb/persistent.go
go/zodb/persistent.go
+5
-0
go/zodb/zodbpy.go
go/zodb/zodbpy.go
+13
-7
No files found.
go/zodb/connection.go
View file @
922b606d
...
@@ -112,7 +112,7 @@ type LiveCacheControl interface {
...
@@ -112,7 +112,7 @@ type LiveCacheControl interface {
// XXX type Class string ?
// XXX type Class string ?
// function representing new of a class.
// function representing new of a class.
type
classNewFunc
func
(
base
*
P
yPersistent
)
IPyPersistent
// XXX Py -> ø
type
classNewFunc
func
(
base
*
P
ersistent
)
IPersistent
// {} class -> new(pyobj XXX)
// {} class -> new(pyobj XXX)
var
classTab
=
make
(
map
[
string
]
classNewFunc
)
var
classTab
=
make
(
map
[
string
]
classNewFunc
)
...
@@ -129,36 +129,36 @@ func RegisterClass(class string, classNew classNewFunc) {
...
@@ -129,36 +129,36 @@ func RegisterClass(class string, classNew classNewFunc) {
// 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
{
pyobj
:=
&
PyPersistent
{
base
:=
&
Persistent
{
class
:
class
,
jar
:
conn
,
oid
:
oid
,
serial
:
0
,
state
:
GHOST
}
Persistent
:
Persistent
{
jar
:
conn
,
oid
:
oid
,
serial
:
0
,
state
:
GHOST
},
pyclass
:
pyclass
,
}
// switch on pyclass and transform e.g. "zodb.BTree.Bucket" -> *ZBucket
// switch on pyclass and transform e.g. "zodb.BTree.Bucket" -> *ZBucket
classNew
:=
classTab
[
class
]
classNew
:=
classTab
[
class
]
var
instance
IPersistent
var
instance
IPersistent
if
classNew
!=
nil
{
if
classNew
!=
nil
{
instance
=
classNew
(
pyobj
)
instance
=
classNew
(
base
)
}
else
{
}
else
{
instance
=
&
Broken
{
P
yPersistent
:
pyobj
}
instance
=
&
Broken
{
P
ersistent
:
base
}
}
}
pyobj
.
instance
=
instance
base
.
instance
=
instance
return
instance
return
instance
}
}
// 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
pystate
interface
{}
// XXX py -> ø ?
state
*
mem
.
Buf
}
}
func
(
b
*
Broken
)
DropState
()
{
func
(
b
*
Broken
)
DropState
()
{
b
.
pystate
=
nil
b
.
state
.
XRelease
()
b
.
state
=
nil
}
}
func
(
b
*
Broken
)
PySetState
(
pystate
interface
{})
error
{
func
(
b
*
Broken
)
SetState
(
state
*
mem
.
Buf
)
error
{
b
.
pystate
=
pystate
b
.
state
.
XRelease
()
state
.
Incref
()
b
.
state
=
state
return
nil
return
nil
}
}
...
@@ -206,7 +206,7 @@ func (conn *Connection) get(class string, oid Oid) (IPersistent, error) {
...
@@ -206,7 +206,7 @@ func (conn *Connection) get(class string, oid Oid) (IPersistent, error) {
if
checkClass
{
if
checkClass
{
// XXX get obj class via reflection?
// XXX get obj class via reflection?
if
cls
:=
obj
.
PyC
lass
();
class
!=
cls
{
if
cls
:=
obj
.
zc
lass
();
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
...
...
go/zodb/persistent.go
View file @
922b606d
...
@@ -31,6 +31,8 @@ import (
...
@@ -31,6 +31,8 @@ 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?
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.
...
@@ -117,6 +119,8 @@ const (
...
@@ -117,6 +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
{
class
string
// zodb class of this object. XXX try not to store and retrieve via reflect?
jar
*
Connection
jar
*
Connection
oid
Oid
oid
Oid
serial
Tid
serial
Tid
...
@@ -128,6 +132,7 @@ type Persistent struct {
...
@@ -128,6 +132,7 @@ type Persistent struct {
loading
*
loadState
loading
*
loadState
}
}
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
}
...
...
go/zodb/zodbpy.go
View file @
922b606d
...
@@ -28,7 +28,7 @@ import (
...
@@ -28,7 +28,7 @@ import (
type
IPyPersistent
interface
{
type
IPyPersistent
interface
{
IPersistent
IPersistent
PyClass
()
pickle
.
Class
// python class of this object
//
PyClass() pickle.Class // python class of this object
// PyState() interface{} // object state. python passes this to pyclass.__new__().__setstate__()
// PyState() interface{} // object state. python passes this to pyclass.__new__().__setstate__()
// IPyPersistent must be stateful for persistency to work
// IPyPersistent must be stateful for persistency to work
...
@@ -44,7 +44,7 @@ type PyPersistent struct {
...
@@ -44,7 +44,7 @@ type PyPersistent struct {
pyclass
pickle
.
Class
pyclass
pickle
.
Class
}
}
func
(
pyobj
*
PyPersistent
)
PyClass
()
pickle
.
Class
{
return
pyobj
.
pyclass
}
//
func (pyobj *PyPersistent) PyClass() pickle.Class { return pyobj.pyclass }
//func (pyobj *PyPersistent) PyState() interface{} { return pyobj.pystate }
//func (pyobj *PyPersistent) PyState() interface{} { return pyobj.pystate }
// PyStateful is the interface describing in-RAM object whose data state can be
// PyStateful is the interface describing in-RAM object whose data state can be
...
@@ -75,10 +75,11 @@ func (pyobj *PyPersistent) SetState(state *mem.Buf) error {
...
@@ -75,10 +75,11 @@ func (pyobj *PyPersistent) SetState(state *mem.Buf) error {
return
err
// XXX err ctx
return
err
// XXX err ctx
}
}
if
pyclass
!=
pyobj
.
pyclass
{
class
:=
pyclassPath
(
pyclass
)
if
class
!=
pyobj
.
class
{
// 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
.
pyclass
,
have
:
py
class
}
// XXX + err ctx
return
&
wrongClassError
{
want
:
pyobj
.
class
,
have
:
class
}
// XXX + err ctx
}
}
return
pyobj
.
pyinstance
()
.
PySetState
(
pystate
)
// XXX err ctx = ok?
return
pyobj
.
pyinstance
()
.
PySetState
(
pystate
)
// XXX err ctx = ok?
...
@@ -143,6 +144,12 @@ func (d *dummyPyInstance) PySetState(pystate interface{}) error {
...
@@ -143,6 +144,12 @@ func (d *dummyPyInstance) PySetState(pystate interface{}) error {
// ----------------------------------------
// ----------------------------------------
// pyclassPath returns full path for a python class.
//
// for example class "ABC" in module "wendelin.lib" has its full path as "wendelin.lib.ABC".
func
pyclassPath
(
pyclass
pickle
.
Class
)
string
{
return
pyclass
.
Module
+
"."
+
pyclass
.
Name
}
// 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.
//
//
...
@@ -156,11 +163,10 @@ func (conn *Connection) loadpy(ctx context.Context, oid Oid) (class string, pyst
...
@@ -156,11 +163,10 @@ func (conn *Connection) loadpy(ctx context.Context, oid Oid) (class string, pyst
defer
buf
.
Release
()
defer
buf
.
Release
()
pyclass
,
pystate
,
err
=
PyData
(
buf
.
Data
)
.
Decode
()
pyclass
,
pystate
,
err
:
=
PyData
(
buf
.
Data
)
.
Decode
()
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
nil
,
0
,
err
// XXX err ctx
return
""
,
nil
,
0
,
err
// XXX err ctx
}
}
class
:=
pyclass
.
Module
+
"."
+
pyclass
.
Name
// full pyclass path
return
pyclassPath
(
pyclass
),
pystate
,
serial
,
nil
return
class
,
pystate
,
serial
,
nil
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment