Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZODB
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
Kirill Smelkov
ZODB
Commits
824123b8
Commit
824123b8
authored
Apr 23, 2010
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cross-database wekrefs weren't handled correctly.
https://bugs.launchpad.net/zodb/+bug/435547
parent
8fd960bc
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
105 additions
and
13 deletions
+105
-13
src/CHANGES.txt
src/CHANGES.txt
+4
-0
src/ZODB/ConflictResolution.py
src/ZODB/ConflictResolution.py
+5
-1
src/ZODB/ConflictResolution.txt
src/ZODB/ConflictResolution.txt
+11
-1
src/ZODB/serialize.py
src/ZODB/serialize.py
+27
-10
src/persistent/wref.py
src/persistent/wref.py
+58
-1
No files found.
src/CHANGES.txt
View file @
824123b8
...
@@ -22,6 +22,10 @@ Bugs Fixed
...
@@ -22,6 +22,10 @@ Bugs Fixed
https://bugs.launchpad.net/zodb/+bug/428039
https://bugs.launchpad.net/zodb/+bug/428039
- cross-database wekrefs weren't handled correctly.
https://bugs.launchpad.net/zodb/+bug/435547
- The mkzeoinst script was fixed to tell people to
- The mkzeoinst script was fixed to tell people to
install and use the mkzeoinstance script. :)
install and use the mkzeoinstance script. :)
...
...
src/ZODB/ConflictResolution.py
View file @
824123b8
...
@@ -116,13 +116,17 @@ class PersistentReference(object):
...
@@ -116,13 +116,17 @@ class PersistentReference(object):
# 'm' = multi_persistent: (database_name, oid, klass)
# 'm' = multi_persistent: (database_name, oid, klass)
# 'n' = multi_oid: (database_name, oid)
# 'n' = multi_oid: (database_name, oid)
# 'w' = persistent weakref: (oid)
# 'w' = persistent weakref: (oid)
# or persistent weakref: (oid, database_name)
# else it is a weakref: reference_type
# else it is a weakref: reference_type
if
reference_type
==
'm'
:
if
reference_type
==
'm'
:
self
.
database_name
,
self
.
oid
,
self
.
klass
=
data
[
1
]
self
.
database_name
,
self
.
oid
,
self
.
klass
=
data
[
1
]
elif
reference_type
==
'n'
:
elif
reference_type
==
'n'
:
self
.
database_name
,
self
.
oid
=
data
[
1
]
self
.
database_name
,
self
.
oid
=
data
[
1
]
elif
reference_type
==
'w'
:
elif
reference_type
==
'w'
:
try
:
self
.
oid
,
=
data
[
1
]
self
.
oid
,
=
data
[
1
]
except
ValueError
:
self
.
oid
,
self
.
database_name
=
data
[
1
]
self
.
weak
=
True
self
.
weak
=
True
else
:
else
:
assert
len
(
data
)
==
1
,
'unknown reference format'
assert
len
(
data
)
==
1
,
'unknown reference format'
...
...
src/ZODB/ConflictResolution.txt
View file @
824123b8
...
@@ -474,6 +474,16 @@ integrity issues.
...
@@ -474,6 +474,16 @@ integrity issues.
>>> ref3.weak
>>> ref3.weak
True
True
>>> ref3a = PersistentReference(['w', ('my_oid', 'other_db')])
>>> ref3a.oid
'my_oid'
>>> print ref3a.klass
None
>>> ref3a.database_name
'other_db'
>>> ref3a.weak
True
>>> ref4 = PersistentReference(['m', ('other_db', 'my_oid', 'my_class')])
>>> ref4 = PersistentReference(['m', ('other_db', 'my_oid', 'my_class')])
>>> ref4.oid
>>> ref4.oid
'my_oid'
'my_oid'
...
@@ -508,7 +518,7 @@ integrity issues.
...
@@ -508,7 +518,7 @@ integrity issues.
>>> ref1 == ref1 and ref2 == ref2 and ref4 == ref4 and ref5 == ref5
>>> ref1 == ref1 and ref2 == ref2 and ref4 == ref4 and ref5 == ref5
True
True
>>> ref3 == ref3 and ref6 == ref6 # weak references
>>> ref3 == ref3 and ref
3a == ref3a and ref
6 == ref6 # weak references
True
True
Non-weak references with the same oid and database_name are equal.
Non-weak references with the same oid and database_name are equal.
...
...
src/ZODB/serialize.py
View file @
824123b8
...
@@ -100,7 +100,8 @@ oid
...
@@ -100,7 +100,8 @@ oid
The following reference types are defined:
The following reference types are defined:
'w'
'w'
Persistent weak reference. The arguments consist of an oid.
Persistent weak reference. The arguments consist of an oid
and optionally a database name.
The following are planned for the future:
The following are planned for the future:
...
@@ -298,8 +299,8 @@ class ObjectWriter:
...
@@ -298,8 +299,8 @@ class ObjectWriter:
oid
=
obj
.
oid
oid
=
obj
.
oid
if
oid
is
None
:
if
oid
is
None
:
obj
=
obj
()
# get the referenced object
target
=
obj
()
# get the referenced object
oid
=
obj
.
_p_oid
oid
=
target
.
_p_oid
if
oid
is
None
:
if
oid
is
None
:
# Here we are causing the object to be saved in
# Here we are causing the object to be saved in
# the database. One could argue that we shouldn't
# the database. One could argue that we shouldn't
...
@@ -308,10 +309,16 @@ class ObjectWriter:
...
@@ -308,10 +309,16 @@ class ObjectWriter:
# assume that the object will be added eventually.
# assume that the object will be added eventually.
oid
=
self
.
_jar
.
new_oid
()
oid
=
self
.
_jar
.
new_oid
()
obj
.
_p_jar
=
self
.
_jar
target
.
_p_jar
=
self
.
_jar
obj
.
_p_oid
=
oid
target
.
_p_oid
=
oid
self
.
_stack
.
append
(
obj
)
self
.
_stack
.
append
(
target
)
obj
.
oid
=
oid
obj
.
dm
=
target
.
_p_jar
obj
.
database_name
=
obj
.
dm
.
db
().
database_name
if
obj
.
dm
is
self
.
_jar
:
return
[
'w'
,
(
oid
,
)]
return
[
'w'
,
(
oid
,
)]
else
:
return
[
'w'
,
(
oid
,
obj
.
database_name
)]
# Since we have an oid, we have either a persistent instance
# Since we have an oid, we have either a persistent instance
...
@@ -530,10 +537,20 @@ class ObjectReader:
...
@@ -530,10 +537,20 @@ class ObjectReader:
loaders
[
'm'
]
=
load_multi_persistent
loaders
[
'm'
]
=
load_multi_persistent
def
load_persistent_weakref
(
self
,
oid
):
def
load_persistent_weakref
(
self
,
oid
,
database_name
=
None
):
obj
=
WeakRef
.
__new__
(
WeakRef
)
obj
=
WeakRef
.
__new__
(
WeakRef
)
obj
.
oid
=
oid
obj
.
oid
=
oid
if
database_name
is
None
:
obj
.
dm
=
self
.
_conn
obj
.
dm
=
self
.
_conn
else
:
obj
.
database_name
=
database_name
try
:
obj
.
dm
=
self
.
_conn
.
get_connection
(
database_name
)
except
KeyError
:
# XXX Not sure what to do here. It seems wrong to
# fail since this is a weak reference. For now we'll
# just pretend that the target object has gone.
pass
return
obj
return
obj
loaders
[
'w'
]
=
load_persistent_weakref
loaders
[
'w'
]
=
load_persistent_weakref
...
@@ -649,7 +666,7 @@ def referencesf(p, oids=None):
...
@@ -649,7 +666,7 @@ def referencesf(p, oids=None):
return
oids
return
oids
oid_klass_loaders
=
{
oid_klass_loaders
=
{
'w'
:
lambda
oid
:
None
,
'w'
:
lambda
oid
,
database_name
=
None
:
None
,
}
}
def
get_refs
(
a_pickle
):
def
get_refs
(
a_pickle
):
...
...
src/persistent/wref.py
View file @
824123b8
...
@@ -99,6 +99,61 @@ class WeakRef(object):
...
@@ -99,6 +99,61 @@ class WeakRef(object):
Always explicitly close databases: :)
Always explicitly close databases: :)
>>> db.close()
>>> db.close()
>>> del ob, ref, db, conn1, conn2, conn3
When multiple databases are in use, a weakref in one database may
point to an object in a different database. Let's create two new
databases to demonstrate this.
>>> dbA = ZODB.tests.util.DB(
... database_name = 'dbA',
... )
>>> dbB = ZODB.tests.util.DB(
... database_name = 'dbB',
... databases = dbA.databases,
... )
>>> connA1 = dbA.open()
>>> connB1 = connA1.get_connection('dbB')
Now create and add a new object and a weak reference, and add them
to different databases.
>>> ob = ZODB.tests.MinPO.MinPO()
>>> ref = WeakRef(ob)
>>> connA1.root()['ob'] = ob
>>> connA1.add(ob)
>>> connB1.root()['ref'] = ref
>>> transaction.commit()
After a succesful commit, the reference should know the oid,
database name and connection of the object.
>>> ref.oid == ob._p_oid
True
>>> ref.database_name == 'dbA'
True
>>> ref.dm is ob._p_jar is connA1
True
If we open new connections, we should be able to use the reference.
>>> connA2 = dbA.open()
>>> connB2 = connA2.get_connection('dbB')
>>> ref2 = connB2.root()['ref']
>>> ob2 = connA2.root()['ob']
>>> ref2() is ob2
True
>>> ref2.oid == ob2._p_oid
True
>>> ref2.database_name == 'dbA'
True
>>> ref2.dm is ob2._p_jar is connA2
True
Always explicitly close databases: :)
>>> dbA.close()
>>> dbB.close()
"""
"""
...
@@ -110,6 +165,8 @@ class WeakRef(object):
...
@@ -110,6 +165,8 @@ class WeakRef(object):
self
.
_v_ob
=
ob
self
.
_v_ob
=
ob
self
.
oid
=
ob
.
_p_oid
self
.
oid
=
ob
.
_p_oid
self
.
dm
=
ob
.
_p_jar
self
.
dm
=
ob
.
_p_jar
if
self
.
dm
is
not
None
:
self
.
database_name
=
self
.
dm
.
db
().
database_name
def
__call__
(
self
):
def
__call__
(
self
):
try
:
try
:
...
@@ -117,7 +174,7 @@ class WeakRef(object):
...
@@ -117,7 +174,7 @@ class WeakRef(object):
except
AttributeError
:
except
AttributeError
:
try
:
try
:
self
.
_v_ob
=
self
.
dm
[
self
.
oid
]
self
.
_v_ob
=
self
.
dm
[
self
.
oid
]
except
KeyError
:
except
(
KeyError
,
AttributeError
)
:
return
None
return
None
return
self
.
_v_ob
return
self
.
_v_ob
...
...
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