solentware-base 5.2.2__tar.gz → 5.2.3__tar.gz
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.
- {solentware_base-5.2.2/solentware_base.egg-info → solentware_base-5.2.3}/PKG-INFO +4 -19
- {solentware_base-5.2.2 → solentware_base-5.2.3}/pyproject.toml +4 -4
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_database.py +4 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_databasedu.py +1 -1
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_db.py +5 -2
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_db_tkinter.py +5 -2
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_dbdu.py +21 -8
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_dbdu_tkinter.py +21 -8
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_dpt.py +6 -1
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_lmdb.py +1 -1
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_lmdbdu.py +21 -8
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_nosql.py +31 -3
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_nosqldu.py +1 -1
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_sqlite.py +103 -63
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_sqlitedu.py +1 -1
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/merge.py +6 -3
- {solentware_base-5.2.2 → solentware_base-5.2.3/solentware_base.egg-info}/PKG-INFO +4 -19
- {solentware_base-5.2.2 → solentware_base-5.2.3}/LICENCE +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/MANIFEST.in +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/README +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/setup.cfg +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/__init__.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/apsw_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/apswdu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/berkeleydb_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/berkeleydbdu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/bsddb3_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/bsddb3du_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/__init__.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/_bytebit.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/bytebit.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/constants.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/cursor.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/filespec.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/find.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/findvalues.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/record.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/recordset.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/recordsetbasecursor.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/recordsetcursor.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/segmentsize.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/tree.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/where.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/core/wherevalues.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/db_tcl.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/db_tkinter_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/db_tkinterdu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/dpt_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/dptdu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/dptfastload_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/gnu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/gnu_module.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/gnudu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/lmdb_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/lmdbdu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/modulequery.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/ndbm_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/ndbm_module.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/ndbmdu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/sqlite3_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/sqlite3du_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/__init__.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/base_3_to_4.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/base_3_to_4_db.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/base_3_to_4_sqlite.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/berkeleydb_du_splice_fix.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/compare_dpt_tape_files.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/create_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/sqlite_table_name_upgrade.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/traverse_dpt_tape_files.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/ui_base_3_to_4.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/unqlite_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/unqlitedu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/vedis_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/vedisdu_database.py +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base.egg-info/SOURCES.txt +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base.egg-info/dependency_links.txt +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base.egg-info/top_level.txt +0 -0
- {solentware_base-5.2.2 → solentware_base-5.2.3}/tox.ini +0 -0
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: solentware-base
|
|
3
|
-
Version: 5.2.
|
|
3
|
+
Version: 5.2.3
|
|
4
4
|
Summary: Bitmapped record number databases.
|
|
5
5
|
Author-email: Roger Marsh <roger.marsh@solentware.co.uk>
|
|
6
|
-
License:
|
|
7
|
-
Copyright (c) 2009, Roger Marsh
|
|
8
|
-
All rights reserved.
|
|
9
|
-
|
|
10
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
14
|
-
|
|
15
|
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
16
|
-
|
|
17
|
-
Neither the name of the owner nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
21
|
-
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
22
7
|
Project-URL: Homepage, http://www.solentware.co.uk
|
|
23
8
|
Project-URL: Repository, https://github.com/RogerMarsh/solentware-base.git
|
|
24
9
|
Project-URL: Bug Tracker, https://github.com/RogerMarsh/solentware-base/issues
|
|
25
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
26
10
|
Classifier: Programming Language :: Python :: 3.9
|
|
27
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
28
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -32,6 +16,7 @@ Classifier: Topic :: Database
|
|
|
32
16
|
Classifier: Intended Audience :: Developers
|
|
33
17
|
Classifier: Development Status :: 3 - Alpha
|
|
34
18
|
License-File: LICENCE
|
|
19
|
+
Dynamic: license-file
|
|
35
20
|
|
|
36
21
|
=========================================================================
|
|
37
22
|
A bitmapped record number database interface for various database engines
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[build-system]
|
|
2
2
|
requires = [
|
|
3
|
-
"setuptools>=
|
|
3
|
+
"setuptools>=77.0.3",
|
|
4
4
|
"wheel"
|
|
5
5
|
]
|
|
6
6
|
build-backend = "setuptools.build_meta"
|
|
@@ -10,13 +10,12 @@ line-length = 79
|
|
|
10
10
|
|
|
11
11
|
[project]
|
|
12
12
|
name = "solentware-base"
|
|
13
|
-
version = "5.2.
|
|
13
|
+
version = "5.2.3"
|
|
14
14
|
authors = [
|
|
15
15
|
{ name="Roger Marsh", email="roger.marsh@solentware.co.uk" },
|
|
16
16
|
]
|
|
17
17
|
description = "Bitmapped record number databases."
|
|
18
18
|
classifiers = [
|
|
19
|
-
"License :: OSI Approved :: BSD License",
|
|
20
19
|
"Programming Language :: Python :: 3.9",
|
|
21
20
|
"Programming Language :: Python :: 3.10",
|
|
22
21
|
"Programming Language :: Python :: 3.11",
|
|
@@ -26,7 +25,8 @@ classifiers = [
|
|
|
26
25
|
"Intended Audience :: Developers",
|
|
27
26
|
"Development Status :: 3 - Alpha",
|
|
28
27
|
]
|
|
29
|
-
license =
|
|
28
|
+
license = "BSD-3-Clause"
|
|
29
|
+
license-files = ["LICENCE"]
|
|
30
30
|
readme = "README"
|
|
31
31
|
|
|
32
32
|
[project.urls]
|
|
@@ -63,7 +63,7 @@ _openbsd_platform = sys.platform.startswith("openbsd")
|
|
|
63
63
|
del sys
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
class DatabaseError(
|
|
66
|
+
class DatabaseError(_database.DatabaseError):
|
|
67
67
|
"""Exception for Database class."""
|
|
68
68
|
|
|
69
69
|
|
|
@@ -549,7 +549,10 @@ class Database(_database.Database):
|
|
|
549
549
|
for field in specification[SECONDARY]:
|
|
550
550
|
secondary = SUBFILE_DELIMITER.join((file, field))
|
|
551
551
|
if secondary in self.table:
|
|
552
|
-
|
|
552
|
+
try:
|
|
553
|
+
self.table[secondary].close()
|
|
554
|
+
except AttributeError:
|
|
555
|
+
pass
|
|
553
556
|
self.table[secondary] = None
|
|
554
557
|
for k, dbo in self.table.items():
|
|
555
558
|
if dbo is not None:
|
|
@@ -62,7 +62,7 @@ _openbsd_platform = sys.platform.startswith("openbsd")
|
|
|
62
62
|
del sys
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
class DatabaseError(
|
|
65
|
+
class DatabaseError(_database.DatabaseError):
|
|
66
66
|
"""Exception for Database class."""
|
|
67
67
|
|
|
68
68
|
|
|
@@ -713,7 +713,10 @@ class Database(_database.Database):
|
|
|
713
713
|
# careless about deleting closed secondary database DB
|
|
714
714
|
# objects in deferred update mode. Exceptions occur
|
|
715
715
|
# here if that is allowed to happen with the Tcl API.
|
|
716
|
-
|
|
716
|
+
try:
|
|
717
|
+
tcl_tk_call((self.table[secondary], "close"))
|
|
718
|
+
except AttributeError:
|
|
719
|
+
pass
|
|
717
720
|
self.table[secondary] = None
|
|
718
721
|
for k, dbo in self.table.items():
|
|
719
722
|
if dbo is not None:
|
|
@@ -21,7 +21,7 @@ from .recordset import (
|
|
|
21
21
|
from . import _databasedu
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class DatabaseError(
|
|
24
|
+
class DatabaseError(_databasedu.DatabaseduError):
|
|
25
25
|
"""Exception for Database class."""
|
|
26
26
|
|
|
27
27
|
|
|
@@ -481,7 +481,7 @@ class Database(_databasedu.Database):
|
|
|
481
481
|
assert len(record) == 2
|
|
482
482
|
value, segment = record
|
|
483
483
|
if len(segment) == 6:
|
|
484
|
-
count = b"x00\x01"
|
|
484
|
+
count = b"\x00\x01"
|
|
485
485
|
reference = segment[4:]
|
|
486
486
|
else:
|
|
487
487
|
count = segment[4:6]
|
|
@@ -529,17 +529,23 @@ class Database(_databasedu.Database):
|
|
|
529
529
|
self.prev_key = item[0]
|
|
530
530
|
item_type = item.pop(2)
|
|
531
531
|
if item_type == EXISTING_SEGMENT_REFERENCE:
|
|
532
|
-
self.cursor.put(item[0], b"".join(item[1:]), keylast)
|
|
533
532
|
assert len(item) == 4
|
|
533
|
+
if item[-2] == b"\x00\x01":
|
|
534
|
+
item.pop(-2)
|
|
535
|
+
self.cursor.put(item[0], b"".join(item[1:]), keylast)
|
|
536
|
+
length = len(b"".join(item[1:]))
|
|
537
|
+
assert length == 10 or length == 6
|
|
534
538
|
return
|
|
535
539
|
if int.from_bytes(item[-2], byteorder="big") > 1:
|
|
536
540
|
item[-1] = segment_table.append(
|
|
537
541
|
item[-1], txn=self.database.dbtxn
|
|
538
542
|
).to_bytes(4, byteorder="big")
|
|
539
543
|
assert len(item) == 4
|
|
544
|
+
assert len(b"".join(item[1:])) == 10
|
|
540
545
|
else:
|
|
541
546
|
item.pop(2)
|
|
542
547
|
assert len(item) == 3
|
|
548
|
+
assert len(b"".join(item[1:])) == 6
|
|
543
549
|
self.cursor.put(item[0], b"".join(item[1:]), keylast)
|
|
544
550
|
assert item_type == NEW_SEGMENT_CONTENT
|
|
545
551
|
return
|
|
@@ -547,22 +553,22 @@ class Database(_databasedu.Database):
|
|
|
547
553
|
assert item[2] == NEW_SEGMENT_CONTENT
|
|
548
554
|
del item[2]
|
|
549
555
|
high = read_high_item_in_index(self.cursor)
|
|
550
|
-
|
|
556
|
+
new_segment = make_segment_from_item(item)
|
|
557
|
+
new_segment |= make_segment_from_high(
|
|
551
558
|
high, self.database.dbtxn
|
|
552
559
|
)
|
|
553
|
-
new_segment = make_segment_from_item(item)
|
|
554
|
-
new_segment |= existing_segment
|
|
555
560
|
new_segment.normalize()
|
|
556
561
|
item[-2] = (
|
|
557
562
|
self.database.encode_number_for_sequential_file_dump(
|
|
558
563
|
new_segment.count_records(), 2
|
|
559
564
|
)
|
|
560
565
|
)
|
|
561
|
-
if
|
|
566
|
+
if high[2] == b"\x00\x01":
|
|
562
567
|
item[-1] = segment_table.append(
|
|
563
568
|
new_segment.tobytes(), txn=self.database.dbtxn
|
|
564
569
|
).to_bytes(4, byteorder="big")
|
|
565
570
|
self.cursor.delete()
|
|
571
|
+
assert len(b"".join(item[1:])) == 10
|
|
566
572
|
self.cursor.put(item[0], b"".join(item[1:]), keylast)
|
|
567
573
|
else:
|
|
568
574
|
segment_table.put(
|
|
@@ -572,14 +578,19 @@ class Database(_databasedu.Database):
|
|
|
572
578
|
)
|
|
573
579
|
self.cursor.delete()
|
|
574
580
|
item[-1] = high[-1]
|
|
581
|
+
assert len(b"".join(item[1:])) == 10
|
|
575
582
|
self.cursor.put(item[0], b"".join(item[1:]), keylast)
|
|
576
583
|
assert len(item) == 4
|
|
577
584
|
return
|
|
578
585
|
item_type = item.pop(2)
|
|
579
586
|
if item_type == EXISTING_SEGMENT_REFERENCE:
|
|
587
|
+
assert len(item) == 4
|
|
580
588
|
self.prev_key = item[0]
|
|
589
|
+
if item[-2] == b"\x00\x01":
|
|
590
|
+
item.pop(-2)
|
|
581
591
|
self.cursor.put(item[0], b"".join(item[1:]), keylast)
|
|
582
|
-
|
|
592
|
+
length = len(b"".join(item[1:]))
|
|
593
|
+
assert length == 10 or length == 6
|
|
583
594
|
return
|
|
584
595
|
if int.from_bytes(item[-2], byteorder="big") > 1:
|
|
585
596
|
item[-1] = segment_table.append(
|
|
@@ -587,9 +598,11 @@ class Database(_databasedu.Database):
|
|
|
587
598
|
txn=self.database.dbtxn,
|
|
588
599
|
).to_bytes(4, byteorder="big")
|
|
589
600
|
assert len(item) == 4
|
|
601
|
+
assert len(b"".join(item[1:])) == 10
|
|
590
602
|
else:
|
|
591
603
|
item.pop(2)
|
|
592
604
|
assert len(item) == 3
|
|
605
|
+
assert len(b"".join(item[1:])) == 6
|
|
593
606
|
self.cursor.put(item[0], b"".join(item[1:]), keylast)
|
|
594
607
|
assert item_type == NEW_SEGMENT_CONTENT
|
|
595
608
|
return
|
|
@@ -22,7 +22,7 @@ from .recordset import (
|
|
|
22
22
|
from . import _databasedu
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class DatabaseError(
|
|
25
|
+
class DatabaseError(_databasedu.DatabaseduError):
|
|
26
26
|
"""Exception for Database class."""
|
|
27
27
|
|
|
28
28
|
|
|
@@ -576,7 +576,7 @@ class Database(_databasedu.Database):
|
|
|
576
576
|
assert len(record) == 1
|
|
577
577
|
value, segment = record[0]
|
|
578
578
|
if len(segment) == 6:
|
|
579
|
-
count = b"x00\x01"
|
|
579
|
+
count = b"\x00\x01"
|
|
580
580
|
reference = segment[4:]
|
|
581
581
|
else:
|
|
582
582
|
count = segment[4:6]
|
|
@@ -664,22 +664,28 @@ class Database(_databasedu.Database):
|
|
|
664
664
|
self.prev_key = item[0]
|
|
665
665
|
item_type = item.pop(2)
|
|
666
666
|
if item_type == EXISTING_SEGMENT_REFERENCE:
|
|
667
|
+
assert len(item) == 4
|
|
668
|
+
if item[-2] == b"\x00\x01":
|
|
669
|
+
item.pop(-2)
|
|
667
670
|
tcl_tk_call(
|
|
668
671
|
tuple(
|
|
669
672
|
self.write_item_to_index
|
|
670
673
|
+ [item[0], b"".join(item[1:])]
|
|
671
674
|
)
|
|
672
675
|
)
|
|
673
|
-
|
|
676
|
+
length = len(b"".join(item[1:]))
|
|
677
|
+
assert length == 10 or length == 6
|
|
674
678
|
return
|
|
675
679
|
if int.from_bytes(item[-2], byteorder="big") > 1:
|
|
676
680
|
item[-1] = tcl_tk_call(
|
|
677
681
|
tuple(self.write_segment_value + [item[-1]])
|
|
678
682
|
).to_bytes(4, byteorder="big")
|
|
679
683
|
assert len(item) == 4
|
|
684
|
+
assert len(b"".join(item[1:])) == 10
|
|
680
685
|
else:
|
|
681
686
|
item.pop(2)
|
|
682
687
|
assert len(item) == 3
|
|
688
|
+
assert len(b"".join(item[1:])) == 6
|
|
683
689
|
tcl_tk_call(
|
|
684
690
|
tuple(
|
|
685
691
|
self.write_item_to_index
|
|
@@ -694,22 +700,22 @@ class Database(_databasedu.Database):
|
|
|
694
700
|
high = read_high_item_in_index(
|
|
695
701
|
self.get_last_record_in_index
|
|
696
702
|
)
|
|
697
|
-
|
|
703
|
+
new_segment = make_segment_from_item(item)
|
|
704
|
+
new_segment |= make_segment_from_high(
|
|
698
705
|
high, self.get_segment_value
|
|
699
706
|
)
|
|
700
|
-
new_segment = make_segment_from_item(item)
|
|
701
|
-
new_segment |= existing_segment
|
|
702
707
|
new_segment.normalize()
|
|
703
708
|
item[-2] = (
|
|
704
709
|
self.database.encode_number_for_sequential_file_dump(
|
|
705
710
|
new_segment.count_records(), 2
|
|
706
711
|
)
|
|
707
712
|
)
|
|
708
|
-
if
|
|
713
|
+
if high[2] == b"\x00\x01":
|
|
709
714
|
item[-1] = tcl_tk_call(
|
|
710
715
|
tuple(self.write_segment_value + [item[-1]])
|
|
711
716
|
).to_bytes(4, byteorder="big")
|
|
712
717
|
tcl_tk_call(tuple(self.delete_index_item))
|
|
718
|
+
assert len(b"".join(item[1:])) == 10
|
|
713
719
|
tcl_tk_call(
|
|
714
720
|
tuple(
|
|
715
721
|
self.write_item_to_index
|
|
@@ -728,6 +734,7 @@ class Database(_databasedu.Database):
|
|
|
728
734
|
)
|
|
729
735
|
tcl_tk_call(tuple(self.delete_index_item))
|
|
730
736
|
item[-1] = high[-1]
|
|
737
|
+
assert len(b"".join(item[1:])) == 10
|
|
731
738
|
tcl_tk_call(
|
|
732
739
|
tuple(
|
|
733
740
|
self.write_item_to_index
|
|
@@ -738,23 +745,29 @@ class Database(_databasedu.Database):
|
|
|
738
745
|
return
|
|
739
746
|
item_type = item.pop(2)
|
|
740
747
|
if item_type == EXISTING_SEGMENT_REFERENCE:
|
|
748
|
+
assert len(item) == 4
|
|
741
749
|
self.prev_key = item[0]
|
|
750
|
+
if item[-2] == b"\x00\x01":
|
|
751
|
+
item.pop(-2)
|
|
742
752
|
tcl_tk_call(
|
|
743
753
|
tuple(
|
|
744
754
|
self.write_item_to_index
|
|
745
755
|
+ [item[0], b"".join(item[1:])]
|
|
746
756
|
)
|
|
747
757
|
)
|
|
748
|
-
|
|
758
|
+
length = len(b"".join(item[1:]))
|
|
759
|
+
assert length == 10 or length == 6
|
|
749
760
|
return
|
|
750
761
|
if int.from_bytes(item[-2], byteorder="big") > 1:
|
|
751
762
|
item[-1] = tcl_tk_call(
|
|
752
763
|
tuple(self.write_segment_value + [item[-1]])
|
|
753
764
|
).to_bytes(4, byteorder="big")
|
|
754
765
|
assert len(item) == 4
|
|
766
|
+
assert len(b"".join(item[1:])) == 10
|
|
755
767
|
else:
|
|
756
768
|
item.pop(2)
|
|
757
769
|
assert len(item) == 3
|
|
770
|
+
assert len(b"".join(item[1:])) == 6
|
|
758
771
|
tcl_tk_call(
|
|
759
772
|
tuple(
|
|
760
773
|
self.write_item_to_index
|
|
@@ -63,7 +63,7 @@ FILE_PARAMETER_LIST = (
|
|
|
63
63
|
SegmentSize.db_segment_size_bytes = TABLE_B_SIZE
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
class DatabaseError(
|
|
66
|
+
class DatabaseError(_database.DatabaseError):
|
|
67
67
|
"""Raise when an exceptional case is encountered in Database class."""
|
|
68
68
|
|
|
69
69
|
|
|
@@ -1292,6 +1292,11 @@ class DPTFile:
|
|
|
1292
1292
|
# Open the file for normal use.
|
|
1293
1293
|
self.open_existing_file(dbenv)
|
|
1294
1294
|
|
|
1295
|
+
# Check requested fields exist.
|
|
1296
|
+
# A RuntimeError is raised by GetFieldAtts() if field does not exist.
|
|
1297
|
+
for field in self.fields:
|
|
1298
|
+
self.opencontext.GetFieldAtts(field)
|
|
1299
|
+
|
|
1295
1300
|
# Permanent instances for efficient file updates.
|
|
1296
1301
|
self.fieldvalue = dptapi.APIFieldValue()
|
|
1297
1302
|
self._putrecordcopy = dptapi.APIStoreRecordTemplate()
|
|
@@ -19,7 +19,7 @@ from .recordset import (
|
|
|
19
19
|
from . import _databasedu
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
class DatabaseError(
|
|
22
|
+
class DatabaseError(_databasedu.DatabaseduError):
|
|
23
23
|
"""Exception for Database class."""
|
|
24
24
|
|
|
25
25
|
|
|
@@ -530,7 +530,7 @@ class Database(_databasedu.Database):
|
|
|
530
530
|
assert len(record) == 2
|
|
531
531
|
value, segment = record
|
|
532
532
|
if len(segment) == 6:
|
|
533
|
-
count = b"x00\x01"
|
|
533
|
+
count = b"\x00\x01"
|
|
534
534
|
reference = segment[4:]
|
|
535
535
|
else:
|
|
536
536
|
count = segment[4:6]
|
|
@@ -587,17 +587,23 @@ class Database(_databasedu.Database):
|
|
|
587
587
|
self.prev_key = item[0]
|
|
588
588
|
item_type = item.pop(2)
|
|
589
589
|
if item_type == EXISTING_SEGMENT_REFERENCE:
|
|
590
|
-
self.cursor.put(item[0], b"".join(item[1:]))
|
|
591
590
|
assert len(item) == 4
|
|
591
|
+
if item[-2] == b"\x00\x01":
|
|
592
|
+
item.pop(-2)
|
|
593
|
+
self.cursor.put(item[0], b"".join(item[1:]))
|
|
594
|
+
length = len(b"".join(item[1:]))
|
|
595
|
+
assert length == 10 or length == 6
|
|
592
596
|
return
|
|
593
597
|
if int.from_bytes(item[-2], byteorder="big") > 1:
|
|
594
598
|
item[-1] = write_segment_value(
|
|
595
599
|
item[-1], self.segment_cursor
|
|
596
600
|
)
|
|
597
601
|
assert len(item) == 4
|
|
602
|
+
assert len(b"".join(item[1:])) == 10
|
|
598
603
|
else:
|
|
599
604
|
item.pop(2)
|
|
600
605
|
assert len(item) == 3
|
|
606
|
+
assert len(b"".join(item[1:])) == 6
|
|
601
607
|
self.cursor.put(item[0], b"".join(item[1:]))
|
|
602
608
|
assert item_type == NEW_SEGMENT_CONTENT
|
|
603
609
|
return
|
|
@@ -605,22 +611,22 @@ class Database(_databasedu.Database):
|
|
|
605
611
|
assert item[2] == NEW_SEGMENT_CONTENT
|
|
606
612
|
del item[2]
|
|
607
613
|
high = read_high_item_in_index(self.cursor)
|
|
608
|
-
|
|
614
|
+
new_segment = make_segment_from_item(item)
|
|
615
|
+
new_segment |= make_segment_from_high(
|
|
609
616
|
high, self.database.dbtxn.transaction
|
|
610
617
|
)
|
|
611
|
-
new_segment = make_segment_from_item(item)
|
|
612
|
-
new_segment |= existing_segment
|
|
613
618
|
new_segment.normalize()
|
|
614
619
|
item[-2] = (
|
|
615
620
|
self.database.encode_number_for_sequential_file_dump(
|
|
616
621
|
new_segment.count_records(), 2
|
|
617
622
|
)
|
|
618
623
|
)
|
|
619
|
-
if
|
|
624
|
+
if high[2] == b"\x00\x01":
|
|
620
625
|
item[-1] = write_segment_value(
|
|
621
626
|
new_segment.tobytes(), self.segment_cursor
|
|
622
627
|
)
|
|
623
628
|
self.cursor.delete()
|
|
629
|
+
assert len(b"".join(item[1:])) == 10
|
|
624
630
|
self.cursor.put(item[0], b"".join(item[1:]))
|
|
625
631
|
else:
|
|
626
632
|
self.database.dbtxn.transaction.put(
|
|
@@ -630,23 +636,30 @@ class Database(_databasedu.Database):
|
|
|
630
636
|
)
|
|
631
637
|
self.cursor.delete()
|
|
632
638
|
item[-1] = high[-1]
|
|
639
|
+
assert len(b"".join(item[1:])) == 10
|
|
633
640
|
self.cursor.put(item[0], b"".join(item[1:]))
|
|
634
641
|
assert len(item) == 4
|
|
635
642
|
return
|
|
636
643
|
item_type = item.pop(2)
|
|
637
644
|
if item_type == EXISTING_SEGMENT_REFERENCE:
|
|
645
|
+
assert len(item) == 4
|
|
638
646
|
self.prev_key = item[0]
|
|
647
|
+
if item[-2] == b"\x00\x01":
|
|
648
|
+
item.pop(-2)
|
|
639
649
|
self.cursor.put(item[0], b"".join(item[1:]))
|
|
640
|
-
|
|
650
|
+
length = len(b"".join(item[1:]))
|
|
651
|
+
assert length == 10 or length == 6
|
|
641
652
|
return
|
|
642
653
|
if int.from_bytes(item[-2], byteorder="big") > 1:
|
|
643
654
|
item[-1] = write_segment_value(
|
|
644
655
|
item[-1], self.segment_cursor
|
|
645
656
|
)
|
|
646
657
|
assert len(item) == 4
|
|
658
|
+
assert len(b"".join(item[1:])) == 10
|
|
647
659
|
else:
|
|
648
660
|
item.pop(2)
|
|
649
661
|
assert len(item) == 3
|
|
662
|
+
assert len(b"".join(item[1:])) == 6
|
|
650
663
|
self.cursor.put(item[0], b"".join(item[1:]))
|
|
651
664
|
assert item_type == NEW_SEGMENT_CONTENT
|
|
652
665
|
return
|
|
@@ -59,7 +59,7 @@ from .recordset import (
|
|
|
59
59
|
)
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
class DatabaseError(
|
|
62
|
+
class DatabaseError(_database.DatabaseError):
|
|
63
63
|
"""Exception for Database class."""
|
|
64
64
|
|
|
65
65
|
|
|
@@ -293,6 +293,12 @@ class Database(_database.Database):
|
|
|
293
293
|
(self.table[CONTROL_FILE], FIELD_REGISTER_KEY.decode())
|
|
294
294
|
)
|
|
295
295
|
|
|
296
|
+
# These two moved from the try clauses just below to keep the tests
|
|
297
|
+
# with memory-only databases passing. Implication is memory-only
|
|
298
|
+
# databases behave differently when adding fields, and the tests no
|
|
299
|
+
# longer truly test the code.
|
|
300
|
+
rsk = None
|
|
301
|
+
rssbk = None
|
|
296
302
|
# The ___control table should be present already if the file exists.
|
|
297
303
|
if self.database_file is not None:
|
|
298
304
|
dbenv = dbclass(self.database_file)
|
|
@@ -300,11 +306,11 @@ class Database(_database.Database):
|
|
|
300
306
|
if specification_key in dbenv:
|
|
301
307
|
rsk = dbenv[specification_key]
|
|
302
308
|
else:
|
|
303
|
-
|
|
309
|
+
pass
|
|
304
310
|
if segment_size_bytes_key in dbenv:
|
|
305
311
|
rssbk = dbenv[segment_size_bytes_key]
|
|
306
312
|
else:
|
|
307
|
-
|
|
313
|
+
pass
|
|
308
314
|
if rsk is not None and rssbk is not None:
|
|
309
315
|
spec_from_db = literal_eval(rsk.decode())
|
|
310
316
|
if self._use_specification_items is not None:
|
|
@@ -383,6 +389,28 @@ class Database(_database.Database):
|
|
|
383
389
|
dbenv = dbclass()
|
|
384
390
|
dbenv.disable_autocommit()
|
|
385
391
|
|
|
392
|
+
if rsk:
|
|
393
|
+
if len(table_register) != len(self.specification) + 1:
|
|
394
|
+
raise DatabaseError(
|
|
395
|
+
"Specification and table register sizes inconsistent"
|
|
396
|
+
)
|
|
397
|
+
if set(self.specification.keys()).difference(table_register):
|
|
398
|
+
raise DatabaseError(
|
|
399
|
+
"Specification and table register content inconsistent"
|
|
400
|
+
)
|
|
401
|
+
for speckey in self.specification:
|
|
402
|
+
if len(self.specification[speckey][SECONDARY]) > len(
|
|
403
|
+
field_register[speckey]
|
|
404
|
+
):
|
|
405
|
+
raise DatabaseError(
|
|
406
|
+
"Specification and field register size inconsistent"
|
|
407
|
+
)
|
|
408
|
+
if set(self.specification[speckey][SECONDARY]).difference(
|
|
409
|
+
set(field_register[speckey])
|
|
410
|
+
):
|
|
411
|
+
raise DatabaseError(
|
|
412
|
+
"Specification and field register content inconsistent"
|
|
413
|
+
)
|
|
386
414
|
self.set_segment_size()
|
|
387
415
|
self.dbenv = dbenv
|
|
388
416
|
if files is None:
|
|
@@ -47,7 +47,7 @@ from .recordset import (
|
|
|
47
47
|
)
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
class DatabaseError(
|
|
50
|
+
class DatabaseError(_database.DatabaseError):
|
|
51
51
|
"""Exception for Database class."""
|
|
52
52
|
|
|
53
53
|
|
|
@@ -161,6 +161,12 @@ class Database(_database.Database):
|
|
|
161
161
|
if not os.path.isdir(self.home_directory):
|
|
162
162
|
raise
|
|
163
163
|
|
|
164
|
+
# These two moved from the try clauses just below to keep the tests
|
|
165
|
+
# with memory-only databases passing. Implication is memory-only
|
|
166
|
+
# databases behave differently when adding fields, and the tests no
|
|
167
|
+
# longer truly test the code.
|
|
168
|
+
rsk = None
|
|
169
|
+
rssbk = None
|
|
164
170
|
# The ___control table should be present already if the file exists.
|
|
165
171
|
if self.database_file is not None:
|
|
166
172
|
dbenv = dbe.Connection(self.database_file)
|
|
@@ -180,12 +186,12 @@ class Database(_database.Database):
|
|
|
180
186
|
cursor.execute(statement, (SPECIFICATION_KEY,))
|
|
181
187
|
rsk = cursor.fetchall()
|
|
182
188
|
except Exception:
|
|
183
|
-
|
|
189
|
+
pass
|
|
184
190
|
try:
|
|
185
191
|
cursor.execute(statement, (SEGMENT_SIZE_BYTES_KEY,))
|
|
186
192
|
rssbk = cursor.fetchall()
|
|
187
193
|
except Exception:
|
|
188
|
-
|
|
194
|
+
pass
|
|
189
195
|
if rsk is not None and rssbk is not None:
|
|
190
196
|
spec_from_db = literal_eval(rsk[0][0])
|
|
191
197
|
if self._use_specification_items is not None:
|
|
@@ -230,91 +236,98 @@ class Database(_database.Database):
|
|
|
230
236
|
self.start_transaction()
|
|
231
237
|
cursor = self.dbenv.cursor()
|
|
232
238
|
self.table[CONTROL_FILE] = CONTROL_FILE
|
|
233
|
-
|
|
234
|
-
(
|
|
235
|
-
create_table,
|
|
236
|
-
CONTROL_FILE,
|
|
237
|
-
"(",
|
|
238
|
-
CONTROL_FILE,
|
|
239
|
-
",",
|
|
240
|
-
SQLITE_VALUE_COLUMN,
|
|
241
|
-
",",
|
|
242
|
-
"primary key",
|
|
243
|
-
"(",
|
|
244
|
-
CONTROL_FILE,
|
|
245
|
-
",",
|
|
246
|
-
SQLITE_VALUE_COLUMN,
|
|
247
|
-
") )",
|
|
248
|
-
)
|
|
249
|
-
)
|
|
250
|
-
cursor.execute(statement)
|
|
251
|
-
for file, specification in self.specification.items():
|
|
252
|
-
if file not in files:
|
|
253
|
-
continue
|
|
254
|
-
fields = specification[SECONDARY]
|
|
255
|
-
self.table[file] = file
|
|
239
|
+
if rsk is None:
|
|
256
240
|
statement = " ".join(
|
|
257
241
|
(
|
|
258
242
|
create_table,
|
|
259
|
-
|
|
243
|
+
CONTROL_FILE,
|
|
260
244
|
"(",
|
|
261
|
-
|
|
262
|
-
|
|
245
|
+
CONTROL_FILE,
|
|
246
|
+
",",
|
|
263
247
|
SQLITE_VALUE_COLUMN,
|
|
264
|
-
"
|
|
265
|
-
|
|
266
|
-
)
|
|
267
|
-
cursor.execute(statement)
|
|
268
|
-
self.ebm_control[file] = ExistenceBitmapControl(file, self)
|
|
269
|
-
segmentfile = SUBFILE_DELIMITER.join((file, SEGMENT_SUFFIX))
|
|
270
|
-
self.segment_table[file] = segmentfile
|
|
271
|
-
statement = " ".join(
|
|
272
|
-
(
|
|
273
|
-
create_table,
|
|
274
|
-
segmentfile,
|
|
248
|
+
",",
|
|
249
|
+
"primary key",
|
|
275
250
|
"(",
|
|
276
|
-
|
|
277
|
-
"
|
|
251
|
+
CONTROL_FILE,
|
|
252
|
+
",",
|
|
253
|
+
SQLITE_VALUE_COLUMN,
|
|
254
|
+
") )",
|
|
278
255
|
)
|
|
279
256
|
)
|
|
280
257
|
cursor.execute(statement)
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
258
|
+
for file, specification in self.specification.items():
|
|
259
|
+
if file not in files:
|
|
260
|
+
continue
|
|
261
|
+
fields = specification[SECONDARY]
|
|
262
|
+
self.table[file] = file
|
|
263
|
+
if rsk is None:
|
|
284
264
|
statement = " ".join(
|
|
285
265
|
(
|
|
286
266
|
create_table,
|
|
287
|
-
|
|
267
|
+
self.table[file],
|
|
288
268
|
"(",
|
|
289
|
-
field,
|
|
290
|
-
",",
|
|
291
|
-
SQLITE_SEGMENT_COLUMN,
|
|
292
|
-
",",
|
|
293
|
-
SQLITE_COUNT_COLUMN,
|
|
294
|
-
",",
|
|
295
269
|
file,
|
|
270
|
+
db_key,
|
|
271
|
+
SQLITE_VALUE_COLUMN,
|
|
296
272
|
")",
|
|
297
273
|
)
|
|
298
274
|
)
|
|
299
275
|
cursor.execute(statement)
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
276
|
+
self.ebm_control[file] = ExistenceBitmapControl(file, self)
|
|
277
|
+
segmentfile = SUBFILE_DELIMITER.join((file, SEGMENT_SUFFIX))
|
|
278
|
+
self.segment_table[file] = segmentfile
|
|
279
|
+
if rsk is None:
|
|
304
280
|
statement = " ".join(
|
|
305
281
|
(
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
"on",
|
|
309
|
-
secondary,
|
|
282
|
+
create_table,
|
|
283
|
+
segmentfile,
|
|
310
284
|
"(",
|
|
311
|
-
|
|
312
|
-
",",
|
|
313
|
-
SQLITE_SEGMENT_COLUMN,
|
|
285
|
+
SQLITE_RECORDS_COLUMN,
|
|
314
286
|
")",
|
|
315
287
|
)
|
|
316
288
|
)
|
|
317
289
|
cursor.execute(statement)
|
|
290
|
+
for field in fields:
|
|
291
|
+
secondary = SUBFILE_DELIMITER.join((file, field))
|
|
292
|
+
self.table[secondary] = secondary
|
|
293
|
+
if rsk is None:
|
|
294
|
+
statement = " ".join(
|
|
295
|
+
(
|
|
296
|
+
create_table,
|
|
297
|
+
secondary,
|
|
298
|
+
"(",
|
|
299
|
+
field,
|
|
300
|
+
",",
|
|
301
|
+
SQLITE_SEGMENT_COLUMN,
|
|
302
|
+
",",
|
|
303
|
+
SQLITE_COUNT_COLUMN,
|
|
304
|
+
",",
|
|
305
|
+
file,
|
|
306
|
+
")",
|
|
307
|
+
)
|
|
308
|
+
)
|
|
309
|
+
cursor.execute(statement)
|
|
310
|
+
else:
|
|
311
|
+
self._raise_if_no_object("table", secondary)
|
|
312
|
+
indexname = "".join(
|
|
313
|
+
(INDEXPREFIX, SUBFILE_DELIMITER.join((file, field)))
|
|
314
|
+
)
|
|
315
|
+
self.index[secondary] = indexname
|
|
316
|
+
if rsk is None:
|
|
317
|
+
statement = " ".join(
|
|
318
|
+
(
|
|
319
|
+
db_create_index,
|
|
320
|
+
indexname,
|
|
321
|
+
"on",
|
|
322
|
+
secondary,
|
|
323
|
+
"(",
|
|
324
|
+
field,
|
|
325
|
+
",",
|
|
326
|
+
SQLITE_SEGMENT_COLUMN,
|
|
327
|
+
")",
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
cursor.execute(statement)
|
|
318
331
|
if self.database_file is not None:
|
|
319
332
|
if rsk is None and rssbk is None:
|
|
320
333
|
statement = " ".join(
|
|
@@ -338,6 +351,33 @@ class Database(_database.Database):
|
|
|
338
351
|
)
|
|
339
352
|
self.commit()
|
|
340
353
|
|
|
354
|
+
def _raise_if_no_object(self, type_, name):
|
|
355
|
+
"""Raise DatabaseError if object of type_ and name does not exist."""
|
|
356
|
+
statement = " ".join(
|
|
357
|
+
(
|
|
358
|
+
"select name from sqlite_master where type",
|
|
359
|
+
"== ?",
|
|
360
|
+
"and name",
|
|
361
|
+
"== ?",
|
|
362
|
+
)
|
|
363
|
+
)
|
|
364
|
+
cursor = self.dbenv.cursor()
|
|
365
|
+
try:
|
|
366
|
+
if cursor.execute(statement, (type_, name)).fetchone() is None:
|
|
367
|
+
raise DatabaseError(
|
|
368
|
+
"".join(
|
|
369
|
+
(
|
|
370
|
+
"Database does not have '",
|
|
371
|
+
type_,
|
|
372
|
+
"' named '",
|
|
373
|
+
name,
|
|
374
|
+
"'",
|
|
375
|
+
)
|
|
376
|
+
)
|
|
377
|
+
)
|
|
378
|
+
finally:
|
|
379
|
+
cursor.close()
|
|
380
|
+
|
|
341
381
|
def close_database_contexts(self, files=None):
|
|
342
382
|
"""Close files in database.
|
|
343
383
|
|
|
@@ -110,9 +110,12 @@ class SortIndiciesToSequentialFiles:
|
|
|
110
110
|
reference.clear()
|
|
111
111
|
count = (self.segment + 1) * SegmentSize.db_segment_size
|
|
112
112
|
self.segment = segment
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
indicies = self.indicies
|
|
114
|
+
for index, values in value.items():
|
|
115
|
+
reference = indicies.get(index)
|
|
116
|
+
if reference is not None:
|
|
117
|
+
for item in values:
|
|
118
|
+
reference.setdefault(item, []).append(key)
|
|
116
119
|
return count
|
|
117
120
|
|
|
118
121
|
def write_segment_to_sequential_file(self, index, reference):
|
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: solentware-base
|
|
3
|
-
Version: 5.2.
|
|
3
|
+
Version: 5.2.3
|
|
4
4
|
Summary: Bitmapped record number databases.
|
|
5
5
|
Author-email: Roger Marsh <roger.marsh@solentware.co.uk>
|
|
6
|
-
License:
|
|
7
|
-
Copyright (c) 2009, Roger Marsh
|
|
8
|
-
All rights reserved.
|
|
9
|
-
|
|
10
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
14
|
-
|
|
15
|
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
16
|
-
|
|
17
|
-
Neither the name of the owner nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
21
|
-
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
22
7
|
Project-URL: Homepage, http://www.solentware.co.uk
|
|
23
8
|
Project-URL: Repository, https://github.com/RogerMarsh/solentware-base.git
|
|
24
9
|
Project-URL: Bug Tracker, https://github.com/RogerMarsh/solentware-base/issues
|
|
25
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
26
10
|
Classifier: Programming Language :: Python :: 3.9
|
|
27
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
28
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -32,6 +16,7 @@ Classifier: Topic :: Database
|
|
|
32
16
|
Classifier: Intended Audience :: Developers
|
|
33
17
|
Classifier: Development Status :: 3 - Alpha
|
|
34
18
|
License-File: LICENCE
|
|
19
|
+
Dynamic: license-file
|
|
35
20
|
|
|
36
21
|
=========================================================================
|
|
37
22
|
A bitmapped record number database interface for various database engines
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/berkeleydb_du_splice_fix.py
RENAMED
|
File without changes
|
{solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/compare_dpt_tape_files.py
RENAMED
|
File without changes
|
|
File without changes
|
{solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/sqlite_table_name_upgrade.py
RENAMED
|
File without changes
|
{solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base/tools/traverse_dpt_tape_files.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{solentware_base-5.2.2 → solentware_base-5.2.3}/solentware_base.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|