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
nexedi
ZODB
Commits
1ebbdf77
Commit
1ebbdf77
authored
Nov 16, 2016
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Document history, undoLog and undoInfo in IDatabase and have them return text
for user_name and description
parent
539e5f82
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
155 additions
and
11 deletions
+155
-11
src/ZODB/DB.py
src/ZODB/DB.py
+12
-3
src/ZODB/interfaces.py
src/ZODB/interfaces.py
+109
-8
src/ZODB/tests/testDB.py
src/ZODB/tests/testDB.py
+34
-0
No files found.
src/ZODB/DB.py
View file @
1ebbdf77
...
@@ -901,7 +901,7 @@ class DB(object):
...
@@ -901,7 +901,7 @@ class DB(object):
See :meth:`ZODB.interfaces.IStorage.history`.
See :meth:`ZODB.interfaces.IStorage.history`.
"""
"""
return
self
.
storage
.
history
(
oid
,
size
)
return
text_transaction_info
(
self
.
storage
.
history
(
oid
,
size
)
)
def
supportsUndo
(
self
):
def
supportsUndo
(
self
):
"""Return whether the database supports undo.
"""Return whether the database supports undo.
...
@@ -920,7 +920,7 @@ class DB(object):
...
@@ -920,7 +920,7 @@ class DB(object):
if
not
self
.
supportsUndo
():
if
not
self
.
supportsUndo
():
return
()
return
()
return
self
.
storage
.
undoLog
(
*
args
,
**
kw
)
return
text_transaction_info
(
self
.
storage
.
undoLog
(
*
args
,
**
kw
)
)
def
undoInfo
(
self
,
*
args
,
**
kw
):
def
undoInfo
(
self
,
*
args
,
**
kw
):
"""Return a sequence of descriptions for transactions.
"""Return a sequence of descriptions for transactions.
...
@@ -929,7 +929,7 @@ class DB(object):
...
@@ -929,7 +929,7 @@ class DB(object):
"""
"""
if
not
self
.
supportsUndo
():
if
not
self
.
supportsUndo
():
return
()
return
()
return
self
.
storage
.
undoInfo
(
*
args
,
**
kw
)
return
text_transaction_info
(
self
.
storage
.
undoInfo
(
*
args
,
**
kw
)
)
def
undoMultiple
(
self
,
ids
,
txn
=
None
):
def
undoMultiple
(
self
,
ids
,
txn
=
None
):
"""Undo multiple transactions identified by ids.
"""Undo multiple transactions identified by ids.
...
@@ -1064,3 +1064,12 @@ def connection(*args, **kw):
...
@@ -1064,3 +1064,12 @@ def connection(*args, **kw):
managing a separate database object.
managing a separate database object.
"""
"""
return
DB
(
*
args
,
**
kw
).
open_then_close_db_when_connection_closes
()
return
DB
(
*
args
,
**
kw
).
open_then_close_db_when_connection_closes
()
transaction_meta_data_text_variables
=
'user_name'
,
'description'
def
text_transaction_info
(
info
):
for
d
in
info
:
for
name
in
transaction_meta_data_text_variables
:
if
name
in
d
:
d
[
name
]
=
d
[
name
].
decode
(
'utf-8'
)
return
info
src/ZODB/interfaces.py
View file @
1ebbdf77
...
@@ -383,7 +383,41 @@ class IDatabase(IStorageDB):
...
@@ -383,7 +383,41 @@ class IDatabase(IStorageDB):
include useful objects.
include useful objects.
"""
"""
# TODO: Should this method be moved into some subinterface?
def
history
(
oid
,
size
=
1
):
"""Return a sequence of history information dictionaries.
Up to size objects (including no objects) may be returned.
The information provides a log of the changes made to the
object. Data are reported in reverse chronological order.
Each dictionary has the following keys:
time
UTC seconds since the epoch (as in time.time) that the
object revision was committed.
tid
The transaction identifier of the transaction that
committed the version.
user_name
The text (unicode) user identifier, if any (or an empty
string) of the user on whos behalf the revision was
committed.
description
The text (unicode) transaction description for the
transaction that committed the revision.
size
The size of the revision data record.
If the transaction had extension items, then these items are
also included if they don't conflict with the keys above.
"""
def
pack
(
t
=
None
,
days
=
0
):
def
pack
(
t
=
None
,
days
=
0
):
"""Pack the storage, deleting unused object revisions.
"""Pack the storage, deleting unused object revisions.
...
@@ -400,7 +434,76 @@ class IDatabase(IStorageDB):
...
@@ -400,7 +434,76 @@ class IDatabase(IStorageDB):
time if t is not specified.
time if t is not specified.
"""
"""
# TODO: Should this method be moved into some subinterface?
def
undoLog
(
first
,
last
,
filter
=
None
):
"""Return a sequence of descriptions for undoable transactions.
Application code should call undoLog() on a DB instance instead of on
the storage directly.
A transaction description is a mapping with at least these keys:
"time": The time, as float seconds since the epoch, when
the transaction committed.
"user_name": The text value of the `.user` attribute on that
transaction.
"description": The text value of the `.description` attribute on
that transaction.
"id`" A bytes uniquely identifying the transaction to the
storage. If it's desired to undo this transaction,
this is the `transaction_id` to pass to `undo()`.
In addition, if any name+value pairs were added to the transaction
by `setExtendedInfo()`, those may be added to the transaction
description mapping too (for example, FileStorage's `undoLog()` does
this).
`filter` is a callable, taking one argument. A transaction
description mapping is passed to `filter` for each potentially
undoable transaction. The sequence returned by `undoLog()` excludes
descriptions for which `filter` returns a false value. By default,
`filter` always returns a true value.
ZEO note: Arbitrary callables cannot be passed from a ZEO client
to a ZEO server, and a ZEO client's implementation of `undoLog()`
ignores any `filter` argument that may be passed. ZEO clients
should use the related `undoInfo()` method instead (if they want
to do filtering).
Now picture a list containing descriptions of all undoable
transactions that pass the filter, most recent transaction first (at
index 0). The `first` and `last` arguments specify the slice of this
(conceptual) list to be returned:
`first`: This is the index of the first transaction description
in the slice. It must be >= 0.
`last`: If >= 0, first:last acts like a Python slice, selecting
the descriptions at indices `first`, first+1, ..., up to
but not including index `last`. At most last-first
descriptions are in the slice, and `last` should be at
least as large as `first` in this case. If `last` is
less than 0, then abs(last) is taken to be the maximum
number of descriptions in the slice (which still begins
at index `first`). When `last` < 0, the same effect
could be gotten by passing the positive first-last for
`last` instead.
"""
def
undoInfo
(
first
=
0
,
last
=-
20
,
specification
=
None
):
"""Return a sequence of descriptions for undoable transactions.
This is like `undoLog()`, except for the `specification` argument.
If given, `specification` is a dictionary, and `undoInfo()`
synthesizes a `filter` function `f` for `undoLog()` such that
`f(desc)` returns true for a transaction description mapping
`desc` if and only if `desc` maps each key in `specification` to
the same value `specification` maps that key to. In other words,
only extensions (or supersets) of `specification` match.
ZEO note: `undoInfo()` passes the `specification` argument from a
ZEO client to its ZEO server (while a ZEO client ignores any `filter`
argument passed to `undoLog()`).
"""
def
undo
(
id
,
txn
=
None
):
def
undo
(
id
,
txn
=
None
):
"""Undo a transaction identified by id.
"""Undo a transaction identified by id.
...
@@ -940,10 +1043,10 @@ class IStorageUndoable(IStorage):
...
@@ -940,10 +1043,10 @@ class IStorageUndoable(IStorage):
"time": The time, as float seconds since the epoch, when
"time": The time, as float seconds since the epoch, when
the transaction committed.
the transaction committed.
"user_name": The value of the `.user` attribute on that
"user_name": The
bytes
value of the `.user` attribute on that
transaction
, **bytes**
.
transaction.
"description": The value of the `.description` attribute on
"description": The
bytes
value of the `.description` attribute on
that transaction
, **bytes**
.
that transaction.
"id`" A bytes uniquely identifying the transaction to the
"id`" A bytes uniquely identifying the transaction to the
storage. If it's desired to undo this transaction,
storage. If it's desired to undo this transaction,
this is the `transaction_id` to pass to `undo()`.
this is the `transaction_id` to pass to `undo()`.
...
@@ -983,7 +1086,6 @@ class IStorageUndoable(IStorage):
...
@@ -983,7 +1086,6 @@ class IStorageUndoable(IStorage):
could be gotten by passing the positive first-last for
could be gotten by passing the positive first-last for
`last` instead.
`last` instead.
"""
"""
# DB pass through
def
undoInfo
(
first
=
0
,
last
=-
20
,
specification
=
None
):
def
undoInfo
(
first
=
0
,
last
=-
20
,
specification
=
None
):
"""Return a sequence of descriptions for undoable transactions.
"""Return a sequence of descriptions for undoable transactions.
...
@@ -1000,7 +1102,6 @@ class IStorageUndoable(IStorage):
...
@@ -1000,7 +1102,6 @@ class IStorageUndoable(IStorage):
ZEO client to its ZEO server (while a ZEO client ignores any `filter`
ZEO client to its ZEO server (while a ZEO client ignores any `filter`
argument passed to `undoLog()`).
argument passed to `undoLog()`).
"""
"""
# DB pass-through
class
IMVCCStorage
(
IStorage
):
class
IMVCCStorage
(
IStorage
):
...
...
src/ZODB/tests/testDB.py
View file @
1ebbdf77
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
# FOR A PARTICULAR PURPOSE.
# FOR A PARTICULAR PURPOSE.
#
#
##############################################################################
##############################################################################
from
six
import
PY2
from
ZODB.tests.MinPO
import
MinPO
from
ZODB.tests.MinPO
import
MinPO
import
doctest
import
doctest
...
@@ -75,6 +76,39 @@ class DBTests(ZODB.tests.util.TestCase):
...
@@ -75,6 +76,39 @@ class DBTests(ZODB.tests.util.TestCase):
import
ZODB.serialize
import
ZODB.serialize
self
.
assertTrue
(
self
.
db
.
references
is
ZODB
.
serialize
.
referencesf
)
self
.
assertTrue
(
self
.
db
.
references
is
ZODB
.
serialize
.
referencesf
)
def
test_history_and_undo_meta_data_text_handlinf
(
self
):
db
=
self
.
db
conn
=
db
.
open
()
for
i
in
range
(
3
):
with
conn
.
transaction_manager
as
t
:
t
.
note
(
u'work %s'
%
i
)
t
.
setUser
(
u'user%s'
%
i
)
conn
.
root
()[
i
]
=
42
conn
.
close
()
from
ZODB.utils
import
z64
def
check
(
info
,
text
):
for
i
,
h
in
enumerate
(
reversed
(
info
)):
for
(
name
,
expect
)
in
((
'description'
,
'work %s'
),
(
'user_name'
,
'/ user%s'
)):
expect
=
expect
%
i
if
not
text
:
expect
=
expect
.
encode
(
'ascii'
)
self
.
assertEqual
(
h
[
name
],
expect
)
if
PY2
:
expect
=
unicode
if
text
else
str
for
name
in
'description'
,
'user_name'
:
self
.
assertTrue
(
isinstance
(
h
[
name
],
expect
))
check
(
db
.
storage
.
history
(
z64
,
3
),
False
)
check
(
db
.
storage
.
undoLog
(
0
,
3
)
,
False
)
check
(
db
.
storage
.
undoInfo
(
0
,
3
)
,
False
)
check
(
db
.
history
(
z64
,
3
),
True
)
check
(
db
.
undoLog
(
0
,
3
)
,
True
)
check
(
db
.
undoInfo
(
0
,
3
)
,
True
)
def
test_invalidateCache
():
def
test_invalidateCache
():
"""The invalidateCache method invalidates a connection caches for all of
"""The invalidateCache method invalidates a connection caches for all of
...
...
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