zlmdb 25.10.1__cp311-cp311-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of zlmdb might be problematic. Click here for more details.
- flatbuffers/__init__.py +19 -0
- flatbuffers/_version.py +17 -0
- flatbuffers/builder.py +776 -0
- flatbuffers/compat.py +86 -0
- flatbuffers/encode.py +42 -0
- flatbuffers/flexbuffers.py +1527 -0
- flatbuffers/number_types.py +181 -0
- flatbuffers/packer.py +42 -0
- flatbuffers/reflection/AdvancedFeatures.py +10 -0
- flatbuffers/reflection/BaseType.py +24 -0
- flatbuffers/reflection/Enum.py +169 -0
- flatbuffers/reflection/EnumVal.py +96 -0
- flatbuffers/reflection/Field.py +208 -0
- flatbuffers/reflection/KeyValue.py +56 -0
- flatbuffers/reflection/Object.py +175 -0
- flatbuffers/reflection/RPCCall.py +131 -0
- flatbuffers/reflection/Schema.py +206 -0
- flatbuffers/reflection/SchemaFile.py +77 -0
- flatbuffers/reflection/Service.py +145 -0
- flatbuffers/reflection/Type.py +98 -0
- flatbuffers/reflection/__init__.py +0 -0
- flatbuffers/table.py +129 -0
- flatbuffers/util.py +43 -0
- zlmdb/__init__.py +312 -0
- zlmdb/_database.py +990 -0
- zlmdb/_errors.py +31 -0
- zlmdb/_meta.py +27 -0
- zlmdb/_pmap.py +1667 -0
- zlmdb/_schema.py +137 -0
- zlmdb/_transaction.py +181 -0
- zlmdb/_types.py +1596 -0
- zlmdb/_version.py +27 -0
- zlmdb/cli.py +41 -0
- zlmdb/flatbuffers/__init__.py +5 -0
- zlmdb/flatbuffers/reflection/AdvancedFeatures.py +10 -0
- zlmdb/flatbuffers/reflection/BaseType.py +25 -0
- zlmdb/flatbuffers/reflection/Enum.py +252 -0
- zlmdb/flatbuffers/reflection/EnumVal.py +144 -0
- zlmdb/flatbuffers/reflection/Field.py +325 -0
- zlmdb/flatbuffers/reflection/KeyValue.py +84 -0
- zlmdb/flatbuffers/reflection/Object.py +260 -0
- zlmdb/flatbuffers/reflection/RPCCall.py +195 -0
- zlmdb/flatbuffers/reflection/Schema.py +301 -0
- zlmdb/flatbuffers/reflection/SchemaFile.py +112 -0
- zlmdb/flatbuffers/reflection/Service.py +213 -0
- zlmdb/flatbuffers/reflection/Type.py +148 -0
- zlmdb/flatbuffers/reflection/__init__.py +0 -0
- zlmdb/flatbuffers/reflection.fbs +152 -0
- zlmdb/lmdb/__init__.py +37 -0
- zlmdb/lmdb/__main__.py +25 -0
- zlmdb/lmdb/_config.py +10 -0
- zlmdb/lmdb/cffi.py +2606 -0
- zlmdb/lmdb/tool.py +670 -0
- zlmdb/tests/lmdb/__init__.py +0 -0
- zlmdb/tests/lmdb/address_book.py +287 -0
- zlmdb/tests/lmdb/crash_test.py +339 -0
- zlmdb/tests/lmdb/cursor_test.py +333 -0
- zlmdb/tests/lmdb/env_test.py +919 -0
- zlmdb/tests/lmdb/getmulti_test.py +92 -0
- zlmdb/tests/lmdb/iteration_test.py +258 -0
- zlmdb/tests/lmdb/package_test.py +70 -0
- zlmdb/tests/lmdb/test_lmdb.py +188 -0
- zlmdb/tests/lmdb/testlib.py +185 -0
- zlmdb/tests/lmdb/tool_test.py +60 -0
- zlmdb/tests/lmdb/txn_test.py +575 -0
- zlmdb/tests/orm/MNodeLog.py +853 -0
- zlmdb/tests/orm/__init__.py +0 -0
- zlmdb/tests/orm/_schema_fbs.py +215 -0
- zlmdb/tests/orm/_schema_mnode_log.py +1201 -0
- zlmdb/tests/orm/_schema_py2.py +250 -0
- zlmdb/tests/orm/_schema_py3.py +307 -0
- zlmdb/tests/orm/_test_flatbuffers.py +144 -0
- zlmdb/tests/orm/_test_serialization.py +144 -0
- zlmdb/tests/orm/test_basic.py +217 -0
- zlmdb/tests/orm/test_etcd.py +275 -0
- zlmdb/tests/orm/test_pmap_indexes.py +466 -0
- zlmdb/tests/orm/test_pmap_types.py +90 -0
- zlmdb/tests/orm/test_pmaps.py +295 -0
- zlmdb/tests/orm/test_select.py +619 -0
- zlmdb-25.10.1.dist-info/METADATA +264 -0
- zlmdb-25.10.1.dist-info/RECORD +86 -0
- zlmdb-25.10.1.dist-info/WHEEL +5 -0
- zlmdb-25.10.1.dist-info/entry_points.txt +2 -0
- zlmdb-25.10.1.dist-info/licenses/LICENSE +137 -0
- zlmdb-25.10.1.dist-info/licenses/NOTICE +41 -0
- zlmdb-25.10.1.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2013-2025 The py-lmdb authors, all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
|
5
|
+
# modification, are permitted only as authorized by the OpenLDAP
|
|
6
|
+
# Public License.
|
|
7
|
+
#
|
|
8
|
+
# A copy of this license is available in the file LICENSE in the
|
|
9
|
+
# top-level directory of the distribution or, alternatively, at
|
|
10
|
+
# <http://www.OpenLDAP.org/license.html>.
|
|
11
|
+
#
|
|
12
|
+
# OpenLDAP is a registered trademark of the OpenLDAP Foundation.
|
|
13
|
+
#
|
|
14
|
+
# Individual files and/or contributed packages may be copyright by
|
|
15
|
+
# other parties and/or subject to additional restrictions.
|
|
16
|
+
#
|
|
17
|
+
# This work also contains materials derived from public sources.
|
|
18
|
+
#
|
|
19
|
+
# Additional information about OpenLDAP can be obtained at
|
|
20
|
+
# <http://www.openldap.org/>.
|
|
21
|
+
#
|
|
22
|
+
|
|
23
|
+
import os
|
|
24
|
+
import sys
|
|
25
|
+
import struct
|
|
26
|
+
import unittest
|
|
27
|
+
import weakref
|
|
28
|
+
|
|
29
|
+
from . import testlib
|
|
30
|
+
from .testlib import B
|
|
31
|
+
from .testlib import INT_TYPES
|
|
32
|
+
from .testlib import BytesType
|
|
33
|
+
|
|
34
|
+
import zlmdb.lmdb as lmdb
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
UINT_0001 = struct.pack("I", 1)
|
|
38
|
+
UINT_0002 = struct.pack("I", 2)
|
|
39
|
+
ULONG_0001 = struct.pack("L", 1) # L != size_t
|
|
40
|
+
ULONG_0002 = struct.pack("L", 2) # L != size_t
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class InitTest(testlib.LmdbTest):
|
|
44
|
+
def tearDown(self):
|
|
45
|
+
testlib.cleanup()
|
|
46
|
+
|
|
47
|
+
def test_closed(self):
|
|
48
|
+
_, env = testlib.temp_env()
|
|
49
|
+
env.close()
|
|
50
|
+
self.assertRaises(Exception, lambda: lmdb.Transaction(env))
|
|
51
|
+
|
|
52
|
+
def test_readonly(self):
|
|
53
|
+
_, env = testlib.temp_env()
|
|
54
|
+
txn = lmdb.Transaction(env)
|
|
55
|
+
# Read txn can't write.
|
|
56
|
+
self.assertRaises(lmdb.ReadonlyError, lambda: txn.put(B("a"), B("")))
|
|
57
|
+
txn.abort()
|
|
58
|
+
|
|
59
|
+
def test_begin_write(self):
|
|
60
|
+
_, env = testlib.temp_env()
|
|
61
|
+
txn = lmdb.Transaction(env, write=True)
|
|
62
|
+
# Write txn can write.
|
|
63
|
+
assert txn.put(B("a"), B(""))
|
|
64
|
+
txn.commit()
|
|
65
|
+
|
|
66
|
+
def test_bind_db(self):
|
|
67
|
+
_, env = testlib.temp_env()
|
|
68
|
+
main = env.open_db(None)
|
|
69
|
+
sub = env.open_db(B("db1"))
|
|
70
|
+
|
|
71
|
+
txn = lmdb.Transaction(env, write=True, db=sub)
|
|
72
|
+
assert txn.put(B("b"), B("")) # -> sub
|
|
73
|
+
assert txn.put(B("a"), B(""), db=main) # -> main
|
|
74
|
+
txn.commit()
|
|
75
|
+
|
|
76
|
+
txn = lmdb.Transaction(env)
|
|
77
|
+
assert txn.get(B("a")) == B("")
|
|
78
|
+
assert txn.get(B("b")) is None
|
|
79
|
+
assert txn.get(B("a"), db=sub) is None
|
|
80
|
+
assert txn.get(B("b"), db=sub) == B("")
|
|
81
|
+
txn.abort()
|
|
82
|
+
|
|
83
|
+
def test_bind_db_methods(self):
|
|
84
|
+
_, env = testlib.temp_env()
|
|
85
|
+
maindb = env.open_db(None)
|
|
86
|
+
db1 = env.open_db(B("d1"))
|
|
87
|
+
txn = lmdb.Transaction(env, write=True, db=db1)
|
|
88
|
+
assert txn.put(B("a"), B("d1"))
|
|
89
|
+
assert txn.get(B("a"), db=db1) == B("d1")
|
|
90
|
+
assert txn.get(B("a"), db=maindb) is None
|
|
91
|
+
assert txn.replace(B("a"), B("d11")) == B("d1")
|
|
92
|
+
assert txn.pop(B("a")) == B("d11")
|
|
93
|
+
assert txn.put(B("a"), B("main"), db=maindb, overwrite=False)
|
|
94
|
+
assert not txn.delete(B("a"))
|
|
95
|
+
txn.abort()
|
|
96
|
+
|
|
97
|
+
def test_parent_readonly(self):
|
|
98
|
+
_, env = testlib.temp_env()
|
|
99
|
+
parent = lmdb.Transaction(env)
|
|
100
|
+
# Nonsensical.
|
|
101
|
+
self.assertRaises(
|
|
102
|
+
lmdb.InvalidParameterError, lambda: lmdb.Transaction(env, parent=parent)
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def test_parent(self):
|
|
106
|
+
_, env = testlib.temp_env()
|
|
107
|
+
parent = lmdb.Transaction(env, write=True)
|
|
108
|
+
parent.put(B("a"), B("a"))
|
|
109
|
+
|
|
110
|
+
child = lmdb.Transaction(env, write=True, parent=parent)
|
|
111
|
+
assert child.get(B("a")) == B("a")
|
|
112
|
+
assert child.put(B("a"), B("b"))
|
|
113
|
+
child.abort()
|
|
114
|
+
|
|
115
|
+
# put() should have rolled back
|
|
116
|
+
assert parent.get(B("a")) == B("a")
|
|
117
|
+
|
|
118
|
+
child = lmdb.Transaction(env, write=True, parent=parent)
|
|
119
|
+
assert child.put(B("a"), B("b"))
|
|
120
|
+
child.commit()
|
|
121
|
+
|
|
122
|
+
# put() should be visible
|
|
123
|
+
assert parent.get(B("a")) == B("b")
|
|
124
|
+
|
|
125
|
+
def test_buffers(self):
|
|
126
|
+
_, env = testlib.temp_env()
|
|
127
|
+
txn = lmdb.Transaction(env, write=True, buffers=True)
|
|
128
|
+
assert txn.put(B("a"), B("a"))
|
|
129
|
+
b = txn.get(B("a"))
|
|
130
|
+
assert b is not None
|
|
131
|
+
assert len(b) == 1
|
|
132
|
+
assert not isinstance(b, type(B("")))
|
|
133
|
+
txn.commit()
|
|
134
|
+
|
|
135
|
+
txn = lmdb.Transaction(env, buffers=False)
|
|
136
|
+
b = txn.get(B("a"))
|
|
137
|
+
assert b is not None
|
|
138
|
+
assert len(b) == 1
|
|
139
|
+
assert isinstance(b, type(B("")))
|
|
140
|
+
txn.abort()
|
|
141
|
+
|
|
142
|
+
@unittest.skipIf(sys.platform.startswith("win"), "No fork on Windows")
|
|
143
|
+
def test_cached_txn_across_fork(self):
|
|
144
|
+
_, env = testlib.temp_env()
|
|
145
|
+
txn = env.begin(write=False)
|
|
146
|
+
del txn
|
|
147
|
+
|
|
148
|
+
if os.fork() != 0:
|
|
149
|
+
# I am the parent
|
|
150
|
+
os.wait() # Wait for child to finish
|
|
151
|
+
txn = env.begin(write=False) # Used to raise MDB_BAD_RSLOT (#346)
|
|
152
|
+
|
|
153
|
+
@unittest.skipIf(sys.platform.startswith("win"), "No fork on Windows")
|
|
154
|
+
def test_child_deleting_transaction(self):
|
|
155
|
+
_, env = testlib.temp_env()
|
|
156
|
+
with env.begin(write=True) as txn:
|
|
157
|
+
txn.put(b"a", b"foo")
|
|
158
|
+
txn = env.begin()
|
|
159
|
+
|
|
160
|
+
r = env.readers()
|
|
161
|
+
assert r != "(no active readers)\n"
|
|
162
|
+
|
|
163
|
+
pid = os.fork()
|
|
164
|
+
if pid == 0:
|
|
165
|
+
del txn # I am the child
|
|
166
|
+
os._exit(0)
|
|
167
|
+
|
|
168
|
+
os.waitpid(pid, 0)
|
|
169
|
+
# Make sure my child didn't mess with my environment
|
|
170
|
+
r2 = env.readers()
|
|
171
|
+
assert r2 == r, "%r != %r" % (r2, r)
|
|
172
|
+
assert txn.get(b"a") == b"foo"
|
|
173
|
+
del txn
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class ContextManagerTest(unittest.TestCase):
|
|
177
|
+
def tearDown(self):
|
|
178
|
+
testlib.cleanup()
|
|
179
|
+
|
|
180
|
+
def test_ok(self):
|
|
181
|
+
path, env = testlib.temp_env()
|
|
182
|
+
txn = env.begin(write=True)
|
|
183
|
+
with txn as txn_:
|
|
184
|
+
assert txn is txn_
|
|
185
|
+
txn.put(B("foo"), B("123"))
|
|
186
|
+
|
|
187
|
+
self.assertRaises(Exception, lambda: txn.get(B("foo")))
|
|
188
|
+
with env.begin() as txn:
|
|
189
|
+
assert txn.get(B("foo")) == B("123")
|
|
190
|
+
|
|
191
|
+
def test_crash(self):
|
|
192
|
+
path, env = testlib.temp_env()
|
|
193
|
+
txn = env.begin(write=True)
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
with txn as txn_:
|
|
197
|
+
txn.put(B("foo"), B("123"))
|
|
198
|
+
txn.put(123, 123)
|
|
199
|
+
except:
|
|
200
|
+
pass
|
|
201
|
+
|
|
202
|
+
self.assertRaises(Exception, lambda: txn.get(B("foo")))
|
|
203
|
+
with env.begin() as txn:
|
|
204
|
+
assert txn.get(B("foo")) is None
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class IdTest(unittest.TestCase):
|
|
208
|
+
def tearDown(self):
|
|
209
|
+
testlib.cleanup()
|
|
210
|
+
|
|
211
|
+
def test_readonly_new(self):
|
|
212
|
+
_, env = testlib.temp_env()
|
|
213
|
+
with env.begin() as txn:
|
|
214
|
+
assert txn.id() == 0
|
|
215
|
+
|
|
216
|
+
def test_write_new(self):
|
|
217
|
+
_, env = testlib.temp_env()
|
|
218
|
+
with env.begin(write=True) as txn:
|
|
219
|
+
assert txn.id() == 1
|
|
220
|
+
|
|
221
|
+
def test_readonly_after_write(self):
|
|
222
|
+
_, env = testlib.temp_env()
|
|
223
|
+
with env.begin(write=True) as txn:
|
|
224
|
+
txn.put(B("a"), B("a"))
|
|
225
|
+
with env.begin() as txn:
|
|
226
|
+
assert txn.id() == 1
|
|
227
|
+
|
|
228
|
+
def test_invalid_txn(self):
|
|
229
|
+
_, env = testlib.temp_env()
|
|
230
|
+
txn = env.begin()
|
|
231
|
+
txn.abort()
|
|
232
|
+
self.assertRaises(Exception, lambda: txn.id())
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class StatTest(unittest.TestCase):
|
|
236
|
+
def tearDown(self):
|
|
237
|
+
testlib.cleanup()
|
|
238
|
+
|
|
239
|
+
def test_stat(self):
|
|
240
|
+
_, env = testlib.temp_env()
|
|
241
|
+
db1 = env.open_db(B("db1"))
|
|
242
|
+
db2 = env.open_db(B("db2"))
|
|
243
|
+
|
|
244
|
+
txn = lmdb.Transaction(env)
|
|
245
|
+
for db in db1, db2:
|
|
246
|
+
stat = txn.stat(db)
|
|
247
|
+
for k in "psize", "depth", "branch_pages", "overflow_pages", "entries":
|
|
248
|
+
assert isinstance(stat[k], INT_TYPES), k
|
|
249
|
+
assert stat[k] >= 0
|
|
250
|
+
assert stat["entries"] == 0
|
|
251
|
+
|
|
252
|
+
txn = lmdb.Transaction(env, write=True)
|
|
253
|
+
txn.put(B("a"), B("b"), db=db1)
|
|
254
|
+
txn.commit()
|
|
255
|
+
|
|
256
|
+
txn = lmdb.Transaction(env)
|
|
257
|
+
stat = txn.stat(db1)
|
|
258
|
+
assert stat["entries"] == 1
|
|
259
|
+
|
|
260
|
+
stat = txn.stat(db2)
|
|
261
|
+
assert stat["entries"] == 0
|
|
262
|
+
|
|
263
|
+
txn.abort()
|
|
264
|
+
self.assertRaises(Exception, lambda: env.stat(db1))
|
|
265
|
+
env.close()
|
|
266
|
+
self.assertRaises(Exception, lambda: env.stat(db1))
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class DropTest(unittest.TestCase):
|
|
270
|
+
def tearDown(self):
|
|
271
|
+
testlib.cleanup()
|
|
272
|
+
|
|
273
|
+
def test_empty(self):
|
|
274
|
+
_, env = testlib.temp_env()
|
|
275
|
+
db1 = env.open_db(B("db1"))
|
|
276
|
+
txn = env.begin(write=True)
|
|
277
|
+
txn.put(B("a"), B("a"), db=db1)
|
|
278
|
+
assert txn.get(B("a"), db=db1) == B("a")
|
|
279
|
+
txn.drop(db1, False)
|
|
280
|
+
assert txn.get(B("a")) is None
|
|
281
|
+
txn.drop(db1, False) # should succeed.
|
|
282
|
+
assert txn.get(B("a")) is None
|
|
283
|
+
|
|
284
|
+
def test_delete(self):
|
|
285
|
+
_, env = testlib.temp_env()
|
|
286
|
+
db1 = env.open_db(B("db1"))
|
|
287
|
+
txn = env.begin(write=True)
|
|
288
|
+
txn.put(B("a"), B("a"), db=db1)
|
|
289
|
+
txn.drop(db1)
|
|
290
|
+
self.assertRaises(lmdb.InvalidParameterError, lambda: txn.get(B("a"), db=db1))
|
|
291
|
+
self.assertRaises(lmdb.InvalidParameterError, lambda: txn.drop(db1))
|
|
292
|
+
|
|
293
|
+
def test_double_delete(self):
|
|
294
|
+
_, env = testlib.temp_env()
|
|
295
|
+
|
|
296
|
+
db1 = env.open_db(B("db1"))
|
|
297
|
+
txn = env.begin(write=True, db=db1)
|
|
298
|
+
txn.put(B("a"), B("a"), db=db1)
|
|
299
|
+
txn.drop(db1)
|
|
300
|
+
self.assertRaises(lmdb.InvalidParameterError, lambda: txn.get(B("a"), db=db1))
|
|
301
|
+
self.assertRaises(lmdb.InvalidParameterError, lambda: txn.drop(db1))
|
|
302
|
+
txn.commit()
|
|
303
|
+
|
|
304
|
+
db1 = env.open_db(B("db1"))
|
|
305
|
+
txn = env.begin(write=True, db=db1)
|
|
306
|
+
txn.put(B("a"), B("a"), db=db1)
|
|
307
|
+
txn.drop(db1)
|
|
308
|
+
self.assertRaises(lmdb.InvalidParameterError, lambda: txn.get(B("a"), db=db1))
|
|
309
|
+
self.assertRaises(lmdb.InvalidParameterError, lambda: txn.drop(db1))
|
|
310
|
+
txn.commit()
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class CommitTest(unittest.TestCase):
|
|
314
|
+
def tearDown(self):
|
|
315
|
+
testlib.cleanup()
|
|
316
|
+
|
|
317
|
+
def test_bad_txn(self):
|
|
318
|
+
_, env = testlib.temp_env()
|
|
319
|
+
txn = env.begin()
|
|
320
|
+
txn.abort()
|
|
321
|
+
self.assertRaises(Exception, lambda: txn.commit())
|
|
322
|
+
|
|
323
|
+
def test_bad_env(self):
|
|
324
|
+
_, env = testlib.temp_env()
|
|
325
|
+
txn = env.begin()
|
|
326
|
+
env.close()
|
|
327
|
+
self.assertRaises(Exception, lambda: txn.commit())
|
|
328
|
+
|
|
329
|
+
def test_commit_ro(self):
|
|
330
|
+
_, env = testlib.temp_env()
|
|
331
|
+
txn = env.begin()
|
|
332
|
+
txn.commit()
|
|
333
|
+
self.assertRaises(Exception, lambda: txn.commit())
|
|
334
|
+
|
|
335
|
+
def test_commit_rw(self):
|
|
336
|
+
_, env = testlib.temp_env()
|
|
337
|
+
txn = env.begin(write=True)
|
|
338
|
+
assert txn.put(B("a"), B("a"))
|
|
339
|
+
txn.commit()
|
|
340
|
+
self.assertRaises(Exception, lambda: txn.commit())
|
|
341
|
+
txn = env.begin()
|
|
342
|
+
assert txn.get(B("a")) == B("a")
|
|
343
|
+
txn.abort()
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
class AbortTest(unittest.TestCase):
|
|
347
|
+
def tearDown(self):
|
|
348
|
+
testlib.cleanup()
|
|
349
|
+
|
|
350
|
+
def test_abort_ro(self):
|
|
351
|
+
_, env = testlib.temp_env()
|
|
352
|
+
txn = env.begin()
|
|
353
|
+
assert txn.get(B("a")) is None
|
|
354
|
+
txn.abort()
|
|
355
|
+
self.assertRaises(Exception, lambda: txn.get(B("a")))
|
|
356
|
+
env.close()
|
|
357
|
+
self.assertRaises(Exception, lambda: txn.get(B("a")))
|
|
358
|
+
|
|
359
|
+
def test_abort_rw(self):
|
|
360
|
+
_, env = testlib.temp_env()
|
|
361
|
+
txn = env.begin(write=True)
|
|
362
|
+
assert txn.put(B("a"), B("a"))
|
|
363
|
+
txn.abort()
|
|
364
|
+
txn = env.begin()
|
|
365
|
+
assert txn.get(B("a")) is None
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
class GetTest(unittest.TestCase):
|
|
369
|
+
def tearDown(self):
|
|
370
|
+
testlib.cleanup()
|
|
371
|
+
|
|
372
|
+
def test_bad_txn(self):
|
|
373
|
+
_, env = testlib.temp_env()
|
|
374
|
+
txn = env.begin()
|
|
375
|
+
txn.abort()
|
|
376
|
+
self.assertRaises(Exception, lambda: txn.get(B("a")))
|
|
377
|
+
|
|
378
|
+
def test_bad_env(self):
|
|
379
|
+
_, env = testlib.temp_env()
|
|
380
|
+
txn = env.begin()
|
|
381
|
+
env.close()
|
|
382
|
+
self.assertRaises(Exception, lambda: txn.get(B("a")))
|
|
383
|
+
|
|
384
|
+
def test_missing(self):
|
|
385
|
+
_, env = testlib.temp_env()
|
|
386
|
+
txn = env.begin()
|
|
387
|
+
assert txn.get(B("a")) is None
|
|
388
|
+
assert txn.get(B("a"), default="default") == "default"
|
|
389
|
+
|
|
390
|
+
def test_empty_key(self):
|
|
391
|
+
_, env = testlib.temp_env()
|
|
392
|
+
txn = env.begin()
|
|
393
|
+
self.assertRaises(lmdb.BadValsizeError, lambda: txn.get(B("")))
|
|
394
|
+
|
|
395
|
+
def test_db(self):
|
|
396
|
+
_, env = testlib.temp_env()
|
|
397
|
+
maindb = env.open_db(None)
|
|
398
|
+
db1 = env.open_db(B("db1"))
|
|
399
|
+
|
|
400
|
+
txn = env.begin()
|
|
401
|
+
assert txn.get(B("a"), db=db1) is None
|
|
402
|
+
txn.abort()
|
|
403
|
+
|
|
404
|
+
txn = env.begin(write=True)
|
|
405
|
+
txn.put(B("a"), B("a"), db=db1)
|
|
406
|
+
txn.commit()
|
|
407
|
+
|
|
408
|
+
txn = env.begin()
|
|
409
|
+
assert txn.get(B("a")) is None
|
|
410
|
+
txn.abort()
|
|
411
|
+
|
|
412
|
+
txn = env.begin(db=db1)
|
|
413
|
+
assert txn.get(B("a")) == B("a")
|
|
414
|
+
assert txn.get(B("a"), db=maindb) is None
|
|
415
|
+
|
|
416
|
+
def test_buffers_no(self):
|
|
417
|
+
_, env = testlib.temp_env()
|
|
418
|
+
txn = env.begin(write=True)
|
|
419
|
+
assert txn.put(B("a"), B("a"))
|
|
420
|
+
assert type(txn.get(B("a"))) is BytesType
|
|
421
|
+
|
|
422
|
+
def test_buffers_yes(self):
|
|
423
|
+
_, env = testlib.temp_env()
|
|
424
|
+
txn = env.begin(write=True, buffers=True)
|
|
425
|
+
assert txn.put(B("a"), B("a"))
|
|
426
|
+
assert type(txn.get(B("a"))) is not BytesType
|
|
427
|
+
|
|
428
|
+
def test_dupsort(self):
|
|
429
|
+
_, env = testlib.temp_env()
|
|
430
|
+
db1 = env.open_db(B("db1"), dupsort=True)
|
|
431
|
+
txn = env.begin(write=True, db=db1)
|
|
432
|
+
assert txn.put(B("a"), B("a"))
|
|
433
|
+
assert txn.put(B("a"), B("b"))
|
|
434
|
+
assert txn.get(B("a")) == B("a")
|
|
435
|
+
|
|
436
|
+
def test_integerkey(self):
|
|
437
|
+
_, env = testlib.temp_env()
|
|
438
|
+
db1 = env.open_db(B("db1"), integerkey=True)
|
|
439
|
+
txn = env.begin(write=True, db=db1)
|
|
440
|
+
assert txn.put(UINT_0001, B("a"))
|
|
441
|
+
assert txn.put(UINT_0002, B("b"))
|
|
442
|
+
assert txn.get(UINT_0001) == B("a")
|
|
443
|
+
assert txn.get(UINT_0002) == B("b")
|
|
444
|
+
|
|
445
|
+
def test_integerdup(self):
|
|
446
|
+
_, env = testlib.temp_env()
|
|
447
|
+
db1 = env.open_db(B("db1"), dupsort=True, integerdup=True)
|
|
448
|
+
txn = env.begin(write=True, db=db1)
|
|
449
|
+
assert txn.put(UINT_0001, UINT_0002)
|
|
450
|
+
assert txn.put(UINT_0001, UINT_0001)
|
|
451
|
+
assert txn.get(UINT_0001) == UINT_0001
|
|
452
|
+
|
|
453
|
+
def test_dupfixed(self):
|
|
454
|
+
_, env = testlib.temp_env()
|
|
455
|
+
db1 = env.open_db(B("db1"), dupsort=True, dupfixed=True)
|
|
456
|
+
txn = env.begin(write=True, db=db1)
|
|
457
|
+
assert txn.put(B("a"), B("a"))
|
|
458
|
+
assert txn.put(B("a"), B("b"))
|
|
459
|
+
assert txn.get(B("a")) == B("a")
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
class PutTest(unittest.TestCase):
|
|
463
|
+
def tearDown(self):
|
|
464
|
+
testlib.cleanup()
|
|
465
|
+
|
|
466
|
+
def test_bad_txn(self):
|
|
467
|
+
_, env = testlib.temp_env()
|
|
468
|
+
txn = env.begin(write=True)
|
|
469
|
+
txn.abort()
|
|
470
|
+
self.assertRaises(Exception, lambda: txn.put(B("a"), B("a")))
|
|
471
|
+
|
|
472
|
+
def test_bad_env(self):
|
|
473
|
+
_, env = testlib.temp_env()
|
|
474
|
+
txn = env.begin(write=True)
|
|
475
|
+
env.close()
|
|
476
|
+
self.assertRaises(Exception, lambda: txn.put(B("a"), B("a")))
|
|
477
|
+
|
|
478
|
+
def test_ro_txn(self):
|
|
479
|
+
_, env = testlib.temp_env()
|
|
480
|
+
txn = env.begin()
|
|
481
|
+
self.assertRaises(lmdb.ReadonlyError, lambda: txn.put(B("a"), B("a")))
|
|
482
|
+
|
|
483
|
+
def test_empty_key_value(self):
|
|
484
|
+
_, env = testlib.temp_env()
|
|
485
|
+
txn = env.begin(write=True)
|
|
486
|
+
self.assertRaises(lmdb.BadValsizeError, lambda: txn.put(B(""), B("a")))
|
|
487
|
+
|
|
488
|
+
def test_dupsort(self):
|
|
489
|
+
_, env = testlib.temp_env()
|
|
490
|
+
|
|
491
|
+
def test_dupdata_no_dupsort(self):
|
|
492
|
+
_, env = testlib.temp_env()
|
|
493
|
+
txn = env.begin(write=True)
|
|
494
|
+
assert txn.put(B("a"), B("a"), dupdata=True)
|
|
495
|
+
assert txn.put(B("a"), B("b"), dupdata=True)
|
|
496
|
+
txn.get(B("a"))
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
class ReplaceTest(unittest.TestCase):
|
|
500
|
+
def tearDown(self):
|
|
501
|
+
testlib.cleanup()
|
|
502
|
+
|
|
503
|
+
def test_bad_txn(self):
|
|
504
|
+
_, env = testlib.temp_env()
|
|
505
|
+
txn = env.begin(write=True)
|
|
506
|
+
txn.abort()
|
|
507
|
+
self.assertRaises(Exception, lambda: txn.replace(B("a"), B("a")))
|
|
508
|
+
|
|
509
|
+
def test_bad_env(self):
|
|
510
|
+
_, env = testlib.temp_env()
|
|
511
|
+
txn = env.begin(write=True)
|
|
512
|
+
env.close()
|
|
513
|
+
self.assertRaises(Exception, lambda: txn.replace(B("a"), B("a")))
|
|
514
|
+
|
|
515
|
+
def test_ro_txn(self):
|
|
516
|
+
_, env = testlib.temp_env()
|
|
517
|
+
txn = env.begin()
|
|
518
|
+
self.assertRaises(lmdb.ReadonlyError, lambda: txn.replace(B("a"), B("a")))
|
|
519
|
+
|
|
520
|
+
def test_empty_key_value(self):
|
|
521
|
+
_, env = testlib.temp_env()
|
|
522
|
+
txn = env.begin(write=True)
|
|
523
|
+
self.assertRaises(lmdb.BadValsizeError, lambda: txn.replace(B(""), B("a")))
|
|
524
|
+
|
|
525
|
+
def test_dupsort_noexist(self):
|
|
526
|
+
_, env = testlib.temp_env()
|
|
527
|
+
db = env.open_db(B("db1"), dupsort=True)
|
|
528
|
+
txn = env.begin(write=True, db=db)
|
|
529
|
+
assert None is txn.replace(B("a"), B("x"))
|
|
530
|
+
assert B("x") == txn.replace(B("a"), B("y"))
|
|
531
|
+
assert B("y") == txn.replace(B("a"), B("z"))
|
|
532
|
+
cur = txn.cursor()
|
|
533
|
+
assert cur.set_key(B("a"))
|
|
534
|
+
assert [B("z")] == list(cur.iternext_dup())
|
|
535
|
+
|
|
536
|
+
def test_dupsort_del_none(self):
|
|
537
|
+
_, env = testlib.temp_env()
|
|
538
|
+
db = env.open_db(B("db1"), dupsort=True)
|
|
539
|
+
with env.begin(write=True, db=db) as txn:
|
|
540
|
+
assert txn.put(B("a"), B("a"))
|
|
541
|
+
assert txn.put(B("a"), B("b"))
|
|
542
|
+
cur = txn.cursor()
|
|
543
|
+
assert cur.set_key(B("a"))
|
|
544
|
+
assert [B("a"), B("b")] == list(cur.iternext_dup())
|
|
545
|
+
assert txn.delete(B("a"), None)
|
|
546
|
+
|
|
547
|
+
def test_dupdata_no_dupsort(self):
|
|
548
|
+
_, env = testlib.temp_env()
|
|
549
|
+
txn = env.begin(write=True)
|
|
550
|
+
assert txn.put(B("a"), B("a"), dupdata=True)
|
|
551
|
+
assert txn.put(B("a"), B("b"), dupdata=True)
|
|
552
|
+
txn.get(B("a"))
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
class LeakTest(unittest.TestCase):
|
|
556
|
+
def tearDown(self):
|
|
557
|
+
testlib.cleanup()
|
|
558
|
+
|
|
559
|
+
def test_open_close(self):
|
|
560
|
+
temp_dir = testlib.temp_dir()
|
|
561
|
+
env = lmdb.open(temp_dir)
|
|
562
|
+
with env.begin() as txn:
|
|
563
|
+
pass
|
|
564
|
+
env.close()
|
|
565
|
+
r1 = weakref.ref(env)
|
|
566
|
+
r2 = weakref.ref(txn)
|
|
567
|
+
env = None
|
|
568
|
+
txn = None
|
|
569
|
+
testlib.debug_collect()
|
|
570
|
+
assert r1() is None
|
|
571
|
+
assert r2() is None
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
if __name__ == "__main__":
|
|
575
|
+
unittest.main()
|