Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
zodbtools
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
zodbtools
Commits
bfa739a8
Commit
bfa739a8
authored
Apr 30, 2023
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
debug/junk
parent
3e5ee282
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
82 additions
and
19 deletions
+82
-19
.gitignore
.gitignore
+1
-1
zodbtools/zodbcmp.py
zodbtools/zodbcmp.py
+12
-1
zodbtools/zodbcommit.py
zodbtools/zodbcommit.py
+31
-10
zodbtools/zodbdump.py
zodbtools/zodbdump.py
+18
-2
zodbtools/zodbsync.py
zodbtools/zodbsync.py
+20
-5
No files found.
.gitignore
View file @
bfa739a8
/dist
/dist
/zodbtools.egg-info
/zodbtools.egg-info
/**/**.pyc
/.tox/
/.tox/
/venv
/venv
/venv2
/venv2
...
...
zodbtools/zodbcmp.py
View file @
bfa739a8
...
@@ -36,6 +36,12 @@ from zodbtools.util import ashex, inf, nextitem, txnobjv, parse_tidrange, TidRan
...
@@ -36,6 +36,12 @@ from zodbtools.util import ashex, inf, nextitem, txnobjv, parse_tidrange, TidRan
from
time
import
time
from
time
import
time
from
golang
import
func
,
defer
from
golang
import
func
,
defer
from
ZODB.utils
import
readable_tid_repr
ashex
=
readable_tid_repr
from
ZODB.serialize
import
referencesf
# compare two storage transactions
# compare two storage transactions
# 0 - equal, 1 - non-equal
# 0 - equal, 1 - non-equal
def
txncmp
(
txn1
,
txn2
):
def
txncmp
(
txn1
,
txn2
):
...
@@ -44,12 +50,14 @@ def txncmp(txn1, txn2):
...
@@ -44,12 +50,14 @@ def txncmp(txn1, txn2):
attr1
=
getattr
(
txn1
,
attr
)
attr1
=
getattr
(
txn1
,
attr
)
attr2
=
getattr
(
txn2
,
attr
)
attr2
=
getattr
(
txn2
,
attr
)
if
attr1
!=
attr2
:
if
attr1
!=
attr2
:
import
pdb
;
pdb
.
set_trace
()
return
1
return
1
# data
# data
objv1
=
txnobjv
(
txn1
)
objv1
=
txnobjv
(
txn1
)
objv2
=
txnobjv
(
txn2
)
objv2
=
txnobjv
(
txn2
)
if
len
(
objv1
)
!=
len
(
objv2
):
if
len
(
objv1
)
!=
len
(
objv2
):
import
pdb
;
pdb
.
set_trace
()
return
1
return
1
for
obj1
,
obj2
in
zip
(
objv1
,
objv2
):
for
obj1
,
obj2
in
zip
(
objv1
,
objv2
):
...
@@ -57,6 +65,7 @@ def txncmp(txn1, txn2):
...
@@ -57,6 +65,7 @@ def txncmp(txn1, txn2):
attr1
=
getattr
(
obj1
,
attr
)
attr1
=
getattr
(
obj1
,
attr
)
attr2
=
getattr
(
obj2
,
attr
)
attr2
=
getattr
(
obj2
,
attr
)
if
attr1
!=
attr2
:
if
attr1
!=
attr2
:
import
pdb
;
pdb
.
set_trace
()
return
1
return
1
return
0
return
0
...
@@ -105,7 +114,9 @@ def storcmp(stor1, stor2, tidmin, tidmax, verbose=False):
...
@@ -105,7 +114,9 @@ def storcmp(stor1, stor2, tidmin, tidmax, verbose=False):
tcmp
=
txncmp
(
txn1
,
txn2
)
tcmp
=
txncmp
(
txn1
,
txn2
)
if
tcmp
:
if
tcmp
:
if
verbose
:
if
verbose
:
print
(
"not-equal: transaction %s is different"
)
print
(
"not-equal: transaction %s is different"
%
ashex
(
txn1
.
tid
))
print
([
o1
.
oid
for
(
o1
,
o2
)
in
zip
(
txn1
,
txn2
)
if
o1
.
data
!=
o2
.
data
])
import
pdb
;
pdb
.
set_trace
()
return
1
return
1
...
...
zodbtools/zodbcommit.py
View file @
bfa739a8
...
@@ -40,7 +40,7 @@ can query current database head (last_tid) with `zodb info <stor> last_tid`.
...
@@ -40,7 +40,7 @@ can query current database head (last_tid) with `zodb info <stor> last_tid`.
from
__future__
import
print_function
from
__future__
import
print_function
from
zodbtools
import
zodbdump
from
zodbtools
import
zodbdump
from
zodbtools.util
import
ashex
,
fromhex
,
storageFromURL
,
asbinstream
from
zodbtools.util
import
ashex
,
fromhex
,
s
ha1
,
s
torageFromURL
,
asbinstream
from
ZODB.interfaces
import
IStorageRestoreable
from
ZODB.interfaces
import
IStorageRestoreable
from
ZODB.utils
import
p64
,
u64
,
z64
from
ZODB.utils
import
p64
,
u64
,
z64
from
ZODB.POSException
import
POSKeyError
from
ZODB.POSException
import
POSKeyError
...
@@ -48,6 +48,7 @@ from ZODB._compat import BytesIO
...
@@ -48,6 +48,7 @@ from ZODB._compat import BytesIO
from
golang
import
func
,
defer
,
panic
,
b
from
golang
import
func
,
defer
,
panic
,
b
import
warnings
import
warnings
from
ZODB.utils
import
readable_tid_repr
# zodbcommit commits new transaction into ZODB storage with data specified by
# zodbcommit commits new transaction into ZODB storage with data specified by
# zodbdump transaction.
# zodbdump transaction.
...
@@ -90,14 +91,24 @@ def zodbcommit(stor, at, txn):
...
@@ -90,14 +91,24 @@ def zodbcommit(stor, at, txn):
copy_from
=
None
copy_from
=
None
if
isinstance
(
obj
,
zodbdump
.
ObjectCopy
):
if
isinstance
(
obj
,
zodbdump
.
ObjectCopy
):
copy_from
=
obj
.
copy_from
copy_from
=
obj
.
copy_from
try
:
if
hasattr
(
obj
,
'data'
):
xdata
=
stor
.
loadBefore
(
obj
.
oid
,
p64
(
u64
(
obj
.
copy_from
)
+
1
))
data
=
obj
.
data
except
POSKeyError
:
if
ashex
(
txn
.
tid
)
==
'03a6166ee64176bb'
and
ashex
(
obj
.
oid
)
==
'0000000000083b45'
:
xdata
=
None
print
(
"%s %s => %s"
%
(
readable_tid_repr
(
txn
.
tid
),
ashex
(
obj
.
oid
),
ashex
(
sha1
(
obj
.
data
))))
if
xdata
is
None
:
import
pdb
;
pdb
.
set_trace
()
raise
ValueError
(
"%s: object %s: copy from @%s: no data"
%
else
:
(
runctx
,
ashex
(
obj
.
oid
),
ashex
(
obj
.
copy_from
)))
boom
data
,
_
,
_
=
xdata
try
:
xdata
=
stor
.
loadBefore
(
obj
.
oid
,
p64
(
u64
(
obj
.
copy_from
)
+
1
))
except
POSKeyError
:
xdata
=
None
if
ashex
(
txn
.
tid
)
==
'03a6166ee64176bb'
and
obj
.
oid
==
b'
\
x00
\
x00
\
x00
\
x00
\
x00
\
x08
;E'
:
print
(
ashex
(
txn
.
tid
),
xdata
)
#import pdb; pdb.set_trace()
if
xdata
is
None
:
raise
ValueError
(
"%s: object %s: copy from @%s: no data"
%
(
runctx
,
ashex
(
obj
.
oid
),
ashex
(
obj
.
copy_from
)))
data
,
_
,
_
=
xdata
elif
isinstance
(
obj
,
zodbdump
.
ObjectDelete
):
elif
isinstance
(
obj
,
zodbdump
.
ObjectDelete
):
data
=
None
data
=
None
...
@@ -115,9 +126,19 @@ def zodbcommit(stor, at, txn):
...
@@ -115,9 +126,19 @@ def zodbcommit(stor, at, txn):
# we have the data -> restore/store the object.
# we have the data -> restore/store the object.
# if it will be ConflictError - we just fail and let the caller retry.
# if it will be ConflictError - we just fail and let the caller retry.
if
data
is
None
:
if
data
is
None
:
stor
.
deleteObject
(
obj
.
oid
,
current_serial
(
obj
.
oid
),
txn
)
try
:
curser
=
current_serial
(
obj
.
oid
)
stor
.
deleteObject
(
obj
.
oid
,
curser
,
txn
)
except
:
#import pdb; pdb.set_trace()
raise
else
:
else
:
if
want_restore
and
have_restore
:
if
want_restore
and
have_restore
:
if
0
and
txn
.
status
==
'p'
:
warnings
.
warn
(
"%s is a pack transaction (status p), it will be restored "
"as a commit transaction (status c)"
%
ashex
(
txn
.
tid
))
import
pdb
;
pdb
.
set_trace
()
stor
.
restore
(
obj
.
oid
,
txn
.
tid
,
data
,
''
,
copy_from
,
txn
)
stor
.
restore
(
obj
.
oid
,
txn
.
tid
,
data
,
''
,
copy_from
,
txn
)
else
:
else
:
# FIXME we don't handle copy_from on commit
# FIXME we don't handle copy_from on commit
...
...
zodbtools/zodbdump.py
View file @
bfa739a8
...
@@ -108,6 +108,9 @@ def zodbdump(stor, tidmin, tidmax, hashonly=False, pretty='raw', out=asbinstream
...
@@ -108,6 +108,9 @@ def zodbdump(stor, tidmin, tidmax, hashonly=False, pretty='raw', out=asbinstream
for
txn
in
stor
.
iterator
(
tidmin
,
tidmax
):
for
txn
in
stor
.
iterator
(
tidmin
,
tidmax
):
# XXX .status not covered by IStorageTransactionInformation
# XXX .status not covered by IStorageTransactionInformation
# XXX but covered by BaseStorage.TransactionRecord
# XXX but covered by BaseStorage.TransactionRecord
if
'0000000000083b45'
not
in
[
ashex
(
o
.
oid
)
for
o
in
txn
]:
continue
out
.
write
(
b"txn %s %s
\
n
user %s
\
n
description %s
\
n
"
%
(
out
.
write
(
b"txn %s %s
\
n
user %s
\
n
description %s
\
n
"
%
(
ashex
(
txn
.
tid
),
qq
(
txn
.
status
),
ashex
(
txn
.
tid
),
qq
(
txn
.
status
),
qq
(
txn
.
user
),
qq
(
txn
.
user
),
...
@@ -136,6 +139,9 @@ def zodbdump(stor, tidmin, tidmax, hashonly=False, pretty='raw', out=asbinstream
...
@@ -136,6 +139,9 @@ def zodbdump(stor, tidmin, tidmax, hashonly=False, pretty='raw', out=asbinstream
for
obj
in
objv
:
for
obj
in
objv
:
entry
=
b"obj %s "
%
ashex
(
obj
.
oid
)
entry
=
b"obj %s "
%
ashex
(
obj
.
oid
)
if
b'0000000000083b45'
not
in
entry
:
continue
write_data
=
False
write_data
=
False
if
obj
.
data
is
None
:
if
obj
.
data
is
None
:
...
@@ -143,7 +149,10 @@ def zodbdump(stor, tidmin, tidmax, hashonly=False, pretty='raw', out=asbinstream
...
@@ -143,7 +149,10 @@ def zodbdump(stor, tidmin, tidmax, hashonly=False, pretty='raw', out=asbinstream
# was undo and data taken from obj.data_txn
# was undo and data taken from obj.data_txn
elif
obj
.
data_txn
is
not
None
:
elif
obj
.
data_txn
is
not
None
:
entry
+=
b"from %s"
%
ashex
(
obj
.
data_txn
)
from
ZODB.utils
import
p64
,
u64
,
z64
xdata
=
stor
.
loadBefore
(
obj
.
oid
,
p64
(
u64
(
obj
.
data_txn
)
+
1
))
data
,
_
,
_
=
xdata
entry
+=
b"from %s # %s"
%
(
ashex
(
obj
.
data_txn
),
ashex
(
sha1
(
data
)))
else
:
else
:
# XXX sha1 is hardcoded for now. Dump format allows other hashes.
# XXX sha1 is hardcoded for now. Dump format allows other hashes.
...
@@ -529,6 +538,10 @@ class Object(object):
...
@@ -529,6 +538,10 @@ class Object(object):
def
__init__
(
self
,
oid
):
def
__init__
(
self
,
oid
):
self
.
oid
=
oid
self
.
oid
=
oid
def
__repr__
(
self
):
return
"<%s object for %s at %x>"
%
(
self
.
__class__
.
__name__
,
ashex
(
self
.
oid
),
id
(
self
))
# ObjectDelete represents objects deletion.
# ObjectDelete represents objects deletion.
class
ObjectDelete
(
Object
):
class
ObjectDelete
(
Object
):
...
@@ -541,9 +554,11 @@ class ObjectDelete(Object):
...
@@ -541,9 +554,11 @@ class ObjectDelete(Object):
# ObjectCopy represents object data copy.
# ObjectCopy represents object data copy.
class
ObjectCopy
(
Object
):
class
ObjectCopy
(
Object
):
# .copy_from tid copy object data from object's revision tid
# .copy_from tid copy object data from object's revision tid
def
__init__
(
self
,
oid
,
copy_from
):
def
__init__
(
self
,
oid
,
copy_from
,
data
=
None
):
super
(
ObjectCopy
,
self
).
__init__
(
oid
)
super
(
ObjectCopy
,
self
).
__init__
(
oid
)
self
.
copy_from
=
copy_from
self
.
copy_from
=
copy_from
self
.
data
=
data
def
zdump
(
self
):
def
zdump
(
self
):
return
b'obj %s from %s
\
n
'
%
(
ashex
(
self
.
oid
),
ashex
(
self
.
copy_from
))
return
b'obj %s from %s
\
n
'
%
(
ashex
(
self
.
oid
),
ashex
(
self
.
copy_from
))
...
@@ -553,6 +568,7 @@ class ObjectData(Object):
...
@@ -553,6 +568,7 @@ class ObjectData(Object):
# .data HashOnly | bytes
# .data HashOnly | bytes
# .hashfunc bstr hash function used for integrity
# .hashfunc bstr hash function used for integrity
# .hash_ bytes hash of the object's data
# .hash_ bytes hash of the object's data
# XXX
def
__init__
(
self
,
oid
,
data
,
hashfunc
,
hash_
):
def
__init__
(
self
,
oid
,
data
,
hashfunc
,
hash_
):
super
(
ObjectData
,
self
).
__init__
(
oid
)
super
(
ObjectData
,
self
).
__init__
(
oid
)
self
.
data
=
data
self
.
data
=
data
...
...
zodbtools/zodbsync.py
View file @
bfa739a8
...
@@ -29,10 +29,18 @@ from zodbtools.zodbdump import Transaction, ObjectCopy, ObjectData, ObjectDelete
...
@@ -29,10 +29,18 @@ from zodbtools.zodbdump import Transaction, ObjectCopy, ObjectData, ObjectDelete
from
zodbtools.util
import
ashex
,
parse_tid
,
storageFromURL
,
txnobjv
from
zodbtools.util
import
ashex
,
parse_tid
,
storageFromURL
,
txnobjv
from
ZODB.interfaces
import
IStorageIteration
from
ZODB.interfaces
import
IStorageIteration
from
ZODB.TimeStamp
import
TimeStamp
from
ZODB.utils
import
z64
,
readable_tid_repr
from
ZODB.utils
import
z64
,
readable_tid_repr
from
golang
import
func
,
defer
from
golang
import
func
,
defer
import
logging
logging
.
basicConfig
(
level
=
logging
.
DEBUG
)
def
xxxzodbsync
(
primary_store
,
secondary_store
,
until
,
verbosity
):
secondary_store
.
copyTransactionsFrom
(
primary_store
)
# verbosity > 0)
def
zodbsync
(
primary_store
,
secondary_store
,
until
,
verbosity
):
def
zodbsync
(
primary_store
,
secondary_store
,
until
,
verbosity
):
at
=
secondary_store
.
lastTransaction
()
at
=
secondary_store
.
lastTransaction
()
...
@@ -41,7 +49,7 @@ def zodbsync(primary_store, secondary_store, until, verbosity):
...
@@ -41,7 +49,7 @@ def zodbsync(primary_store, secondary_store, until, verbosity):
print
(
'secondary at'
,
readable_tid_repr
(
at
))
print
(
'secondary at'
,
readable_tid_repr
(
at
))
print
(
"replicating from"
,
readable_tid_repr
(
at
),
end
=
''
)
print
(
"replicating from"
,
readable_tid_repr
(
at
),
end
=
''
)
if
until
:
if
until
:
print
(
"until"
,
readable_tid_repr
(
until
),
end
=
''
)
print
(
"
until"
,
readable_tid_repr
(
until
),
end
=
''
)
print
()
print
()
start
=
datetime
.
datetime
.
now
()
start
=
datetime
.
datetime
.
now
()
...
@@ -54,11 +62,12 @@ def zodbsync(primary_store, secondary_store, until, verbosity):
...
@@ -54,11 +62,12 @@ def zodbsync(primary_store, secondary_store, until, verbosity):
continue
continue
objv
=
[]
objv
=
[]
for
obj
in
t
xnobjv
(
t
):
for
obj
in
t
:
#(txnobjv(t)
):
if
obj
.
data
is
None
:
if
obj
.
data
is
None
:
assert
not
obj
.
data_txn
objv
.
append
(
ObjectDelete
(
obj
.
oid
))
objv
.
append
(
ObjectDelete
(
obj
.
oid
))
elif
obj
.
data_txn
is
not
None
:
elif
obj
.
data_txn
is
not
None
:
objv
.
append
(
ObjectCopy
(
obj
.
oid
,
obj
.
data_txn
))
objv
.
append
(
ObjectCopy
(
obj
.
oid
,
obj
.
data_txn
,
data
=
obj
.
data
))
else
:
else
:
objv
.
append
(
ObjectData
(
obj
.
oid
,
obj
.
data
,
'null'
,
None
))
objv
.
append
(
ObjectData
(
obj
.
oid
,
obj
.
data
,
'null'
,
None
))
...
@@ -72,12 +81,18 @@ def zodbsync(primary_store, secondary_store, until, verbosity):
...
@@ -72,12 +81,18 @@ def zodbsync(primary_store, secondary_store, until, verbosity):
zodbcommit
(
secondary_store
,
at
,
txn
)
zodbcommit
(
secondary_store
,
at
,
txn
)
transaction_count
+=
1
transaction_count
+=
1
if
verbosity
>
0
:
behind
=
TimeStamp
(
primary_store
.
lastTransaction
()).
timeTime
()
-
TimeStamp
(
at
).
timeTime
()
print
(
"behind=%s"
%
behind
)
if
verbosity
>
1
:
if
verbosity
>
1
:
print
(
readable_tid_repr
(
txn
.
tid
),
t
.
user
,
t
.
description
,
len
(
objv
))
print
(
readable_tid_repr
(
txn
.
tid
),
t
.
user
,
t
.
description
,
len
(
objv
)
,
str
(
datetime
.
timedelta
(
seconds
=
behind
))
)
elif
verbosity
>
0
:
elif
verbosity
>
0
:
print
(
readable_tid_repr
(
txn
.
tid
))
print
(
readable_tid_repr
(
txn
.
tid
))
at
=
txn
.
tid
at
=
txn
.
tid
if
verbosity
:
if
verbosity
:
print
(
"replicated %d transactions in %s"
%
(
print
(
"replicated %d transactions in %s"
%
(
transaction_count
,
datetime
.
datetime
.
now
()
-
start
))
transaction_count
,
datetime
.
datetime
.
now
()
-
start
))
...
@@ -128,7 +143,7 @@ def main(argv):
...
@@ -128,7 +143,7 @@ def main(argv):
sys
.
exit
(
2
)
sys
.
exit
(
2
)
primary_store
=
storageFromURL
(
argv
[
0
]
,
read_only
=
True
)
primary_store
=
storageFromURL
(
argv
[
0
]
)
#
read_only=True)
defer
(
primary_store
.
close
)
defer
(
primary_store
.
close
)
secondary_store
=
storageFromURL
(
argv
[
1
])
secondary_store
=
storageFromURL
(
argv
[
1
])
defer
(
secondary_store
.
close
)
defer
(
secondary_store
.
close
)
...
...
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