solentware-base 5.2.3__tar.gz → 5.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.
Files changed (79) hide show
  1. {solentware_base-5.2.3/solentware_base.egg-info → solentware_base-5.3}/PKG-INFO +1 -1
  2. {solentware_base-5.2.3 → solentware_base-5.3}/pyproject.toml +1 -1
  3. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_databasedu.py +12 -0
  4. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_db.py +23 -0
  5. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_db_tkinter.py +34 -0
  6. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_lmdb.py +22 -0
  7. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_sqlite.py +52 -2
  8. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/constants.py +1 -0
  9. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/merge.py +2 -2
  10. {solentware_base-5.2.3 → solentware_base-5.3/solentware_base.egg-info}/PKG-INFO +1 -1
  11. {solentware_base-5.2.3 → solentware_base-5.3}/LICENCE +0 -0
  12. {solentware_base-5.2.3 → solentware_base-5.3}/MANIFEST.in +0 -0
  13. {solentware_base-5.2.3 → solentware_base-5.3}/README +0 -0
  14. {solentware_base-5.2.3 → solentware_base-5.3}/setup.cfg +0 -0
  15. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/__init__.py +0 -0
  16. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/apsw_database.py +0 -0
  17. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/apswdu_database.py +0 -0
  18. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/berkeleydb_database.py +0 -0
  19. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/berkeleydbdu_database.py +0 -0
  20. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/bsddb3_database.py +0 -0
  21. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/bsddb3du_database.py +0 -0
  22. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/__init__.py +0 -0
  23. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_bytebit.py +0 -0
  24. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_database.py +0 -0
  25. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_dbdu.py +0 -0
  26. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_dbdu_tkinter.py +0 -0
  27. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_dpt.py +0 -0
  28. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_lmdbdu.py +0 -0
  29. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_nosql.py +0 -0
  30. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_nosqldu.py +0 -0
  31. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/_sqlitedu.py +0 -0
  32. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/bytebit.py +0 -0
  33. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/cursor.py +0 -0
  34. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/filespec.py +0 -0
  35. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/find.py +0 -0
  36. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/findvalues.py +0 -0
  37. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/record.py +0 -0
  38. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/recordset.py +0 -0
  39. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/recordsetbasecursor.py +0 -0
  40. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/recordsetcursor.py +0 -0
  41. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/segmentsize.py +0 -0
  42. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/tree.py +0 -0
  43. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/where.py +0 -0
  44. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/core/wherevalues.py +0 -0
  45. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/db_tcl.py +0 -0
  46. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/db_tkinter_database.py +0 -0
  47. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/db_tkinterdu_database.py +0 -0
  48. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/dpt_database.py +0 -0
  49. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/dptdu_database.py +0 -0
  50. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/dptfastload_database.py +0 -0
  51. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/gnu_database.py +0 -0
  52. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/gnu_module.py +0 -0
  53. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/gnudu_database.py +0 -0
  54. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/lmdb_database.py +0 -0
  55. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/lmdbdu_database.py +0 -0
  56. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/modulequery.py +0 -0
  57. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/ndbm_database.py +0 -0
  58. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/ndbm_module.py +0 -0
  59. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/ndbmdu_database.py +0 -0
  60. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/sqlite3_database.py +0 -0
  61. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/sqlite3du_database.py +0 -0
  62. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/__init__.py +0 -0
  63. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/base_3_to_4.py +0 -0
  64. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/base_3_to_4_db.py +0 -0
  65. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/base_3_to_4_sqlite.py +0 -0
  66. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/berkeleydb_du_splice_fix.py +0 -0
  67. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/compare_dpt_tape_files.py +0 -0
  68. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/create_database.py +0 -0
  69. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/sqlite_table_name_upgrade.py +0 -0
  70. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/traverse_dpt_tape_files.py +0 -0
  71. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/tools/ui_base_3_to_4.py +0 -0
  72. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/unqlite_database.py +0 -0
  73. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/unqlitedu_database.py +0 -0
  74. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/vedis_database.py +0 -0
  75. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base/vedisdu_database.py +0 -0
  76. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base.egg-info/SOURCES.txt +0 -0
  77. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base.egg-info/dependency_links.txt +0 -0
  78. {solentware_base-5.2.3 → solentware_base-5.3}/solentware_base.egg-info/top_level.txt +0 -0
  79. {solentware_base-5.2.3 → solentware_base-5.3}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: solentware-base
3
- Version: 5.2.3
3
+ Version: 5.3
4
4
  Summary: Bitmapped record number databases.
5
5
  Author-email: Roger Marsh <roger.marsh@solentware.co.uk>
6
6
  License-Expression: BSD-3-Clause
@@ -10,7 +10,7 @@ line-length = 79
10
10
 
11
11
  [project]
12
12
  name = "solentware-base"
13
- version = "5.2.3"
13
+ version = "5.3"
14
14
  authors = [
15
15
  { name="Roger Marsh", email="roger.marsh@solentware.co.uk" },
16
16
  ]
@@ -270,3 +270,15 @@ class Database(_database.Database):
270
270
  merger = merge.Merge(index_directory)
271
271
  for item in merger.sorter():
272
272
  yield item
273
+
274
+ def get_merge_import_sort_area(self):
275
+ """Return database directory.
276
+
277
+ The directory containing database is used for sorting by default,
278
+ subclasses should override as required.
279
+
280
+ There is little point in doing so unless the sort area is then on
281
+ a different drive or mount point.
282
+
283
+ """
284
+ return self.home_directory
@@ -34,6 +34,7 @@ from .constants import (
34
34
  CONTROL_FILE,
35
35
  DEFAULT_SEGMENT_SIZE_BYTES,
36
36
  SPECIFICATION_KEY,
37
+ APPLICATION_CONTROL_KEY,
37
38
  SEGMENT_SIZE_BYTES_KEY,
38
39
  SEGMENT_HEADER_LENGTH,
39
40
  FIELDS,
@@ -496,6 +497,9 @@ class Database(_database.Database):
496
497
  repr(self.segment_size_bytes).encode(),
497
498
  txn=self.dbtxn,
498
499
  )
500
+ self.table[CONTROL_FILE].put(
501
+ APPLICATION_CONTROL_KEY, repr({}).encode(), txn=self.dbtxn
502
+ )
499
503
  self.commit()
500
504
  self._dbe = dbe
501
505
 
@@ -1763,6 +1767,25 @@ class Database(_database.Database):
1763
1767
  return super()._generate_database_file_name(name)
1764
1768
  return os.path.join(self.home_directory, name)
1765
1769
 
1770
+ def get_application_control(self):
1771
+ """Return dict of application control items."""
1772
+ value = self.table[CONTROL_FILE].get(
1773
+ APPLICATION_CONTROL_KEY,
1774
+ txn=self.dbtxn,
1775
+ )
1776
+ if value is not None:
1777
+ return literal_eval(value.decode())
1778
+ return {}
1779
+
1780
+ def set_application_control(self, appcontrol):
1781
+ """Set dict of application control items."""
1782
+ self.table[CONTROL_FILE].delete(
1783
+ APPLICATION_CONTROL_KEY, txn=self.dbtxn
1784
+ )
1785
+ self.table[CONTROL_FILE].put(
1786
+ APPLICATION_CONTROL_KEY, repr(appcontrol).encode(), txn=self.dbtxn
1787
+ )
1788
+
1766
1789
 
1767
1790
  class Cursor(_cursor.Cursor):
1768
1791
  """Define a cursor on the underlying database engine dbset.
@@ -33,6 +33,7 @@ from .constants import (
33
33
  CONTROL_FILE,
34
34
  DEFAULT_SEGMENT_SIZE_BYTES,
35
35
  SPECIFICATION_KEY,
36
+ APPLICATION_CONTROL_KEY,
36
37
  SEGMENT_SIZE_BYTES_KEY,
37
38
  SEGMENT_HEADER_LENGTH,
38
39
  FIELDS,
@@ -638,6 +639,11 @@ class Database(_database.Database):
638
639
  ]
639
640
  )
640
641
  tcl_tk_call(tuple(command))
642
+ command = [self.table[CONTROL_FILE], "put"]
643
+ if self.dbtxn:
644
+ command.extend(["-txn", self.dbtxn])
645
+ command.extend([APPLICATION_CONTROL_KEY, repr({}).encode()])
646
+ tcl_tk_call(tuple(command))
641
647
  self.commit()
642
648
 
643
649
  def _run_db_archive(self):
@@ -2197,6 +2203,34 @@ class Database(_database.Database):
2197
2203
  return super()._generate_database_file_name(name)
2198
2204
  return os.path.join(self.home_directory, name)
2199
2205
 
2206
+ def get_application_control(self):
2207
+ """Return dict of application control items."""
2208
+ command = [self.table[CONTROL_FILE], "get"]
2209
+ if self.dbtxn:
2210
+ command.extend(["-txn", self.dbtxn])
2211
+ command.extend(
2212
+ [
2213
+ APPLICATION_CONTROL_KEY,
2214
+ ]
2215
+ )
2216
+ value = tcl_tk_call(tuple(command))
2217
+ if value is not None:
2218
+ return literal_eval(value.decode())
2219
+ return {}
2220
+
2221
+ def set_application_control(self, appcontrol):
2222
+ """Set dict of application control items."""
2223
+ command = [self.table[CONTROL_FILE], "delete"]
2224
+ if self.dbtxn:
2225
+ command.extend(["-txn", self.dbtxn])
2226
+ command.extend([APPLICATION_CONTROL_KEY])
2227
+ tcl_tk_call(tuple(command))
2228
+ command = [self.table[CONTROL_FILE], "put"]
2229
+ if self.dbtxn:
2230
+ command.extend(["-txn", self.dbtxn])
2231
+ command.extend([APPLICATION_CONTROL_KEY, repr(appcontrol).encode()])
2232
+ tcl_tk_call(tuple(command))
2233
+
2200
2234
 
2201
2235
  class Cursor(_cursor.Cursor):
2202
2236
  """Define a cursor on the underlying database engine dbset.
@@ -18,6 +18,7 @@ from .constants import (
18
18
  DESIGN_FILE,
19
19
  DEFAULT_SEGMENT_SIZE_BYTES,
20
20
  SPECIFICATION_KEY,
21
+ APPLICATION_CONTROL_KEY,
21
22
  SEGMENT_SIZE_BYTES_KEY,
22
23
  SEGMENT_HEADER_LENGTH,
23
24
  DEFAULT_MAP_SIZE,
@@ -343,6 +344,7 @@ class Database(_database.Database):
343
344
  SEGMENT_SIZE_BYTES_KEY,
344
345
  repr(self.segment_size_bytes).encode(),
345
346
  )
347
+ cursor.put(APPLICATION_CONTROL_KEY, repr({}).encode())
346
348
  cursor.close()
347
349
  self.table[DESIGN_FILE].close_datastore()
348
350
  self.open_database_contexts()
@@ -387,6 +389,8 @@ class Database(_database.Database):
387
389
  self._real_segment_size_bytes = False
388
390
  if segment_size != self.segment_size_bytes:
389
391
  self._real_segment_size_bytes = segment_size
392
+ self.dbenv.close()
393
+ self.dbenv = None
390
394
  raise self.SegmentSizeError(
391
395
  " ".join(
392
396
  (
@@ -1847,6 +1851,24 @@ class Database(_database.Database):
1847
1851
  ) // DEFAULT_MAP_PAGES
1848
1852
  self.dbenv.set_mapsize(self.map_blocks * DEFAULT_MAP_SIZE)
1849
1853
 
1854
+ def get_application_control(self):
1855
+ """Return dict of application control items."""
1856
+ value = self.dbtxn.transaction.get(
1857
+ APPLICATION_CONTROL_KEY,
1858
+ db=self.table[DESIGN_FILE].datastore,
1859
+ )
1860
+ if value is not None:
1861
+ return literal_eval(value.decode())
1862
+ return {}
1863
+
1864
+ def set_application_control(self, appcontrol):
1865
+ """Set dict of application control items."""
1866
+ self.dbtxn.transaction.put(
1867
+ APPLICATION_CONTROL_KEY,
1868
+ repr(appcontrol).encode(),
1869
+ db=self.table[DESIGN_FILE].datastore,
1870
+ )
1871
+
1850
1872
 
1851
1873
  class _DBtxn:
1852
1874
  """Provide a Symas LMMD read-only or read-write transaction instance.
@@ -21,6 +21,7 @@ from .constants import (
21
21
  CONTROL_FILE,
22
22
  DEFAULT_SEGMENT_SIZE_BYTES,
23
23
  SPECIFICATION_KEY,
24
+ APPLICATION_CONTROL_KEY,
24
25
  SEGMENT_SIZE_BYTES_KEY,
25
26
  SQLITE_VALUE_COLUMN,
26
27
  SQLITE_SEGMENT_COLUMN,
@@ -124,7 +125,7 @@ class Database(_database.Database):
124
125
  cursor.close()
125
126
 
126
127
  def backout(self):
127
- """Backout tranaction."""
128
+ """Backout transaction."""
128
129
  if self.dbenv:
129
130
  cursor = self.dbenv.cursor()
130
131
  try:
@@ -133,7 +134,7 @@ class Database(_database.Database):
133
134
  cursor.close()
134
135
 
135
136
  def commit(self):
136
- """Commit tranaction."""
137
+ """Commit transaction."""
137
138
  if self.dbenv:
138
139
  cursor = self.dbenv.cursor()
139
140
  try:
@@ -349,6 +350,7 @@ class Database(_database.Database):
349
350
  statement,
350
351
  (SEGMENT_SIZE_BYTES_KEY, repr(self.segment_size_bytes)),
351
352
  )
353
+ cursor.execute(statement, (APPLICATION_CONTROL_KEY, repr({})))
352
354
  self.commit()
353
355
 
354
356
  def _raise_if_no_object(self, type_, name):
@@ -2089,6 +2091,54 @@ class Database(_database.Database):
2089
2091
  finally:
2090
2092
  db.close_database()
2091
2093
 
2094
+ def get_application_control(self):
2095
+ """Return dict of application control items."""
2096
+ cursor = self.dbenv.cursor()
2097
+ statement = " ".join(
2098
+ (
2099
+ "select",
2100
+ SQLITE_VALUE_COLUMN,
2101
+ "from",
2102
+ CONTROL_FILE,
2103
+ "where",
2104
+ CONTROL_FILE,
2105
+ "== ?",
2106
+ )
2107
+ )
2108
+ cursor.execute(statement, (APPLICATION_CONTROL_KEY,))
2109
+ rsk = cursor.fetchall()
2110
+ if rsk:
2111
+ return literal_eval(rsk[0][0])
2112
+ return {}
2113
+
2114
+ def set_application_control(self, appcontrol):
2115
+ """Set dict of application control items."""
2116
+ # Why is 'insert or replace into' on it's own not sufficient.
2117
+ cursor = self.dbenv.cursor()
2118
+ statement = " ".join(
2119
+ (
2120
+ "delete from",
2121
+ CONTROL_FILE,
2122
+ "where",
2123
+ CONTROL_FILE,
2124
+ "== ?",
2125
+ )
2126
+ )
2127
+ cursor.execute(statement, (APPLICATION_CONTROL_KEY,))
2128
+ statement = " ".join(
2129
+ (
2130
+ "insert into",
2131
+ CONTROL_FILE,
2132
+ "(",
2133
+ CONTROL_FILE,
2134
+ ",",
2135
+ SQLITE_VALUE_COLUMN,
2136
+ ")",
2137
+ "values ( ? , ? )",
2138
+ )
2139
+ )
2140
+ cursor.execute(statement, (APPLICATION_CONTROL_KEY, repr(appcontrol)))
2141
+
2092
2142
 
2093
2143
  class Cursor(_cursor.Cursor):
2094
2144
  """Define a cursor on the underlying database engine dbset.
@@ -194,6 +194,7 @@ SPECIFICATION_KEY = b"_specification"
194
194
  SEGMENT_SIZE_BYTES_KEY = b"_segment_size_bytes"
195
195
  TABLE_REGISTER_KEY = b"_table_register"
196
196
  FIELD_REGISTER_KEY = b"_field_register"
197
+ APPLICATION_CONTROL_KEY = b"_application_control"
197
198
 
198
199
  # Constants defined for UnQLite and Vedis databases. dbm.gnu and dbm.ndbm are
199
200
  # added to this list later.
@@ -125,7 +125,7 @@ class SortIndiciesToSequentialFiles:
125
125
  encode_number = database.encode_number_for_sequential_file_dump
126
126
  encode_segment = database.encode_segment_for_sequential_file_dump
127
127
  dump_directory = os.path.join(
128
- database.home_directory,
128
+ database.get_merge_import_sort_area(),
129
129
  "_".join((os.path.basename(database.database_file), self.file)),
130
130
  index,
131
131
  )
@@ -156,7 +156,7 @@ class SortIndiciesToSequentialFiles:
156
156
  self.write_segment_to_sequential_file(index, reference)
157
157
  reference.clear()
158
158
  guard_file = os.path.join(
159
- self.database.home_directory,
159
+ self.database.get_merge_import_sort_area(),
160
160
  "_".join(
161
161
  (os.path.basename(self.database.database_file), self.file)
162
162
  ),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: solentware-base
3
- Version: 5.2.3
3
+ Version: 5.3
4
4
  Summary: Bitmapped record number databases.
5
5
  Author-email: Roger Marsh <roger.marsh@solentware.co.uk>
6
6
  License-Expression: BSD-3-Clause
File without changes
File without changes
File without changes
File without changes