solentware-base 5.2__tar.gz → 5.2.1__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/solentware_base.egg-info → solentware_base-5.2.1}/PKG-INFO +1 -1
- {solentware-base-5.2 → solentware_base-5.2.1}/pyproject.toml +1 -1
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_databasedu.py +3 -3
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_db.py +5 -5
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_db_tkinter.py +7 -5
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_dbdu.py +4 -4
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_dbdu_tkinter.py +4 -4
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_dpt.py +20 -12
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_lmdb.py +5 -5
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_lmdbdu.py +4 -4
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_nosql.py +8 -8
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_nosqldu.py +3 -3
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_sqlite.py +28 -15
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/find.py +4 -2
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/record.py +5 -3
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/where.py +97 -80
- {solentware-base-5.2 → solentware_base-5.2.1/solentware_base.egg-info}/PKG-INFO +1 -1
- {solentware-base-5.2 → solentware_base-5.2.1}/LICENCE +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/MANIFEST.in +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/README +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/setup.cfg +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/__init__.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/apsw_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/apswdu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/berkeleydb_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/berkeleydbdu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/bsddb3_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/bsddb3du_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/__init__.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_bytebit.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/_sqlitedu.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/bytebit.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/constants.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/cursor.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/filespec.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/findvalues.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/merge.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/recordset.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/recordsetbasecursor.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/recordsetcursor.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/segmentsize.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/tree.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/core/wherevalues.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/db_tcl.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/db_tkinter_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/db_tkinterdu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/dpt_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/dptdu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/dptfastload_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/gnu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/gnu_module.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/gnudu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/lmdb_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/lmdbdu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/modulequery.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/ndbm_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/ndbm_module.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/ndbmdu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/sqlite3_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/sqlite3du_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/__init__.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/base_3_to_4.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/base_3_to_4_db.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/base_3_to_4_sqlite.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/berkeleydb_du_splice_fix.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/compare_dpt_tape_files.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/create_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/sqlite_table_name_upgrade.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/traverse_dpt_tape_files.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/ui_base_3_to_4.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/unqlite_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/unqlitedu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/vedis_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/vedisdu_database.py +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base.egg-info/SOURCES.txt +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base.egg-info/dependency_links.txt +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/solentware_base.egg-info/top_level.txt +0 -0
- {solentware-base-5.2 → solentware_base-5.2.1}/tox.ini +0 -0
|
@@ -151,9 +151,9 @@ class Database(_database.Database):
|
|
|
151
151
|
if values[-1] != record_number:
|
|
152
152
|
values.append(record_number)
|
|
153
153
|
if len(values) > SegmentSize.db_upper_conversion_limit:
|
|
154
|
-
vsk = value_segments[
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
vsk = value_segments[key] = (
|
|
155
|
+
SegmentSize.empty_bitarray.copy()
|
|
156
|
+
)
|
|
157
157
|
for j in values:
|
|
158
158
|
vsk[j] = True
|
|
159
159
|
vsk[record_number] = True
|
|
@@ -1414,7 +1414,7 @@ class Database(_database.Database):
|
|
|
1414
1414
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1415
1415
|
if keylike is None:
|
|
1416
1416
|
return recordlist
|
|
1417
|
-
|
|
1417
|
+
matcher = re.compile(keylike)
|
|
1418
1418
|
cursor = self.table[SUBFILE_DELIMITER.join((file, field))].cursor(
|
|
1419
1419
|
txn=self.dbtxn
|
|
1420
1420
|
)
|
|
@@ -1422,7 +1422,7 @@ class Database(_database.Database):
|
|
|
1422
1422
|
record = cursor.first()
|
|
1423
1423
|
while record:
|
|
1424
1424
|
key, value = record
|
|
1425
|
-
if
|
|
1425
|
+
if matcher.search(key):
|
|
1426
1426
|
self.populate_recordset_segment(recordlist, value)
|
|
1427
1427
|
record = cursor.next()
|
|
1428
1428
|
finally:
|
|
@@ -1478,9 +1478,9 @@ class Database(_database.Database):
|
|
|
1478
1478
|
|
|
1479
1479
|
Keys are in range set by combinations of ge, gt, le, and lt.
|
|
1480
1480
|
"""
|
|
1481
|
-
if ge and gt:
|
|
1481
|
+
if isinstance(ge, bytes) and isinstance(gt, bytes):
|
|
1482
1482
|
raise DatabaseError("Both 'ge' and 'gt' given in key range")
|
|
1483
|
-
if le and lt:
|
|
1483
|
+
if isinstance(le, bytes) and isinstance(lt, bytes):
|
|
1484
1484
|
raise DatabaseError("Both 'le' and 'lt' given in key range")
|
|
1485
1485
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1486
1486
|
cursor = self.table[SUBFILE_DELIMITER.join((file, field))].cursor(
|
|
@@ -1490,7 +1490,7 @@ class Database(_database.Database):
|
|
|
1490
1490
|
if ge is None and gt is None:
|
|
1491
1491
|
record = cursor.first()
|
|
1492
1492
|
else:
|
|
1493
|
-
record = cursor.set_range(ge or gt)
|
|
1493
|
+
record = cursor.set_range(ge or gt or b"")
|
|
1494
1494
|
if gt:
|
|
1495
1495
|
while record:
|
|
1496
1496
|
if record[0] > gt:
|
|
@@ -1793,7 +1793,7 @@ class Database(_database.Database):
|
|
|
1793
1793
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1794
1794
|
if keylike is None:
|
|
1795
1795
|
return recordlist
|
|
1796
|
-
|
|
1796
|
+
matcher = re.compile(keylike)
|
|
1797
1797
|
command = [
|
|
1798
1798
|
self.table[SUBFILE_DELIMITER.join((file, field))],
|
|
1799
1799
|
"cursor",
|
|
@@ -1805,7 +1805,7 @@ class Database(_database.Database):
|
|
|
1805
1805
|
record = tcl_tk_call((cursor, "get", "-first"))
|
|
1806
1806
|
while record:
|
|
1807
1807
|
key, value = record[0]
|
|
1808
|
-
if
|
|
1808
|
+
if matcher.search(key):
|
|
1809
1809
|
self.populate_recordset_segment(recordlist, value)
|
|
1810
1810
|
record = tcl_tk_call((cursor, "get", "-next"))
|
|
1811
1811
|
finally:
|
|
@@ -1872,9 +1872,9 @@ class Database(_database.Database):
|
|
|
1872
1872
|
|
|
1873
1873
|
Keys are in range set by combinations of ge, gt, le, and lt.
|
|
1874
1874
|
"""
|
|
1875
|
-
if ge and gt:
|
|
1875
|
+
if isinstance(ge, str) and isinstance(gt, str):
|
|
1876
1876
|
raise DatabaseError("Both 'ge' and 'gt' given in key range")
|
|
1877
|
-
if le and lt:
|
|
1877
|
+
if isinstance(le, str) and isinstance(lt, str):
|
|
1878
1878
|
raise DatabaseError("Both 'le' and 'lt' given in key range")
|
|
1879
1879
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1880
1880
|
command = [
|
|
@@ -1888,7 +1888,9 @@ class Database(_database.Database):
|
|
|
1888
1888
|
if ge is None and gt is None:
|
|
1889
1889
|
record = tcl_tk_call((cursor, "get", "-first"))
|
|
1890
1890
|
else:
|
|
1891
|
-
record = tcl_tk_call(
|
|
1891
|
+
record = tcl_tk_call(
|
|
1892
|
+
(cursor, "get", "-set_range", ge or gt or "")
|
|
1893
|
+
)
|
|
1892
1894
|
if gt:
|
|
1893
1895
|
while record:
|
|
1894
1896
|
record0 = record[0]
|
|
@@ -553,10 +553,10 @@ class Database(_databasedu.Database):
|
|
|
553
553
|
new_segment = make_segment_from_item(item)
|
|
554
554
|
new_segment |= existing_segment
|
|
555
555
|
new_segment.normalize()
|
|
556
|
-
item[
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
556
|
+
item[-2] = (
|
|
557
|
+
self.database.encode_number_for_sequential_file_dump(
|
|
558
|
+
new_segment.count_records(), 2
|
|
559
|
+
)
|
|
560
560
|
)
|
|
561
561
|
if int.from_bytes(high[-2], byteorder="big") == 1:
|
|
562
562
|
item[-1] = segment_table.append(
|
|
@@ -700,10 +700,10 @@ class Database(_databasedu.Database):
|
|
|
700
700
|
new_segment = make_segment_from_item(item)
|
|
701
701
|
new_segment |= existing_segment
|
|
702
702
|
new_segment.normalize()
|
|
703
|
-
item[
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
703
|
+
item[-2] = (
|
|
704
|
+
self.database.encode_number_for_sequential_file_dump(
|
|
705
|
+
new_segment.count_records(), 2
|
|
706
|
+
)
|
|
707
707
|
)
|
|
708
708
|
if int.from_bytes(high[-2], byteorder="big") == 1:
|
|
709
709
|
item[-1] = tcl_tk_call(
|
|
@@ -849,14 +849,14 @@ class Database(_database.Database):
|
|
|
849
849
|
dptapi.APIFieldValue(""),
|
|
850
850
|
)
|
|
851
851
|
)
|
|
852
|
-
matcher = re.compile(
|
|
852
|
+
matcher = re.compile(keylike)
|
|
853
853
|
dvcursor = dptfile.table_connection.OpenDirectValueCursor(
|
|
854
854
|
dptapi.APIFindValuesSpecification(dptfile.secondary[field])
|
|
855
855
|
)
|
|
856
856
|
dvcursor.GotoFirst()
|
|
857
857
|
while dvcursor.Accessible():
|
|
858
858
|
value = dvcursor.GetCurrentValue()
|
|
859
|
-
if matcher.
|
|
859
|
+
if matcher.search(value.ExtractString()):
|
|
860
860
|
vfs = _DPTFoundSet(
|
|
861
861
|
dptfile,
|
|
862
862
|
dptfile.table_connection.FindRecords(
|
|
@@ -961,9 +961,9 @@ class Database(_database.Database):
|
|
|
961
961
|
|
|
962
962
|
cache_size is not relevant to DPT.
|
|
963
963
|
"""
|
|
964
|
-
if ge and gt:
|
|
964
|
+
if isinstance(ge, str) and isinstance(gt, str):
|
|
965
965
|
raise DatabaseError("Both 'ge' and 'gt' given in key range")
|
|
966
|
-
if le and lt:
|
|
966
|
+
if isinstance(le, str) and isinstance(lt, str):
|
|
967
967
|
raise DatabaseError("Both 'le' and 'lt' given in key range")
|
|
968
968
|
if ge is None and gt is None and le is None and lt is None:
|
|
969
969
|
return self.recordlist_all(file, field, cache_size=cache_size)
|
|
@@ -975,8 +975,8 @@ class Database(_database.Database):
|
|
|
975
975
|
dptfile.table_connection.FindRecords(
|
|
976
976
|
dptapi.APIFindSpecification(
|
|
977
977
|
dptfile.secondary[field],
|
|
978
|
-
dptapi.FD_GE if ge else dptapi.FD_GT,
|
|
979
|
-
dptapi.APIFieldValue(ge or gt),
|
|
978
|
+
dptapi.FD_GE if ge is not None else dptapi.FD_GT,
|
|
979
|
+
dptapi.APIFieldValue(ge or gt or ""),
|
|
980
980
|
)
|
|
981
981
|
),
|
|
982
982
|
)
|
|
@@ -986,24 +986,32 @@ class Database(_database.Database):
|
|
|
986
986
|
dptfile.table_connection.FindRecords(
|
|
987
987
|
dptapi.APIFindSpecification(
|
|
988
988
|
dptfile.secondary[field],
|
|
989
|
-
dptapi.FD_LE if le else dptapi.FD_LT,
|
|
990
|
-
dptapi.APIFieldValue(le or lt),
|
|
989
|
+
dptapi.FD_LE if le is not None else dptapi.FD_LT,
|
|
990
|
+
dptapi.APIFieldValue(le or lt or ""),
|
|
991
991
|
)
|
|
992
992
|
),
|
|
993
993
|
)
|
|
994
994
|
else:
|
|
995
995
|
if ge:
|
|
996
|
-
range_ =
|
|
996
|
+
range_ = (
|
|
997
|
+
dptapi.FD_RANGE_GE_LE
|
|
998
|
+
if le is not None
|
|
999
|
+
else dptapi.FD_RANGE_GE_LT
|
|
1000
|
+
)
|
|
997
1001
|
else:
|
|
998
|
-
range_ =
|
|
1002
|
+
range_ = (
|
|
1003
|
+
dptapi.FD_RANGE_GT_LE
|
|
1004
|
+
if le is not None
|
|
1005
|
+
else dptapi.FD_RANGE_GT_LT
|
|
1006
|
+
)
|
|
999
1007
|
foundset = _DPTFoundSet(
|
|
1000
1008
|
dptfile,
|
|
1001
1009
|
dptfile.table_connection.FindRecords(
|
|
1002
1010
|
dptapi.APIFindSpecification(
|
|
1003
1011
|
dptfile.secondary[field],
|
|
1004
1012
|
range_,
|
|
1005
|
-
dptapi.APIFieldValue(ge or gt),
|
|
1006
|
-
dptapi.APIFieldValue(le or lt),
|
|
1013
|
+
dptapi.APIFieldValue(ge or gt or ""),
|
|
1014
|
+
dptapi.APIFieldValue(le or lt or ""),
|
|
1007
1015
|
)
|
|
1008
1016
|
),
|
|
1009
1017
|
)
|
|
@@ -1482,14 +1482,14 @@ class Database(_database.Database):
|
|
|
1482
1482
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1483
1483
|
if keylike is None:
|
|
1484
1484
|
return recordlist
|
|
1485
|
-
|
|
1485
|
+
matcher = re.compile(keylike)
|
|
1486
1486
|
with self.dbtxn.transaction.cursor(
|
|
1487
1487
|
self.table[SUBFILE_DELIMITER.join((file, field))].datastore
|
|
1488
1488
|
) as cursor:
|
|
1489
1489
|
record = cursor.first()
|
|
1490
1490
|
while record:
|
|
1491
1491
|
key, value = cursor.item()
|
|
1492
|
-
if
|
|
1492
|
+
if matcher.search(key):
|
|
1493
1493
|
self.populate_recordset_segment(recordlist, value)
|
|
1494
1494
|
record = cursor.next()
|
|
1495
1495
|
return recordlist
|
|
@@ -1540,9 +1540,9 @@ class Database(_database.Database):
|
|
|
1540
1540
|
|
|
1541
1541
|
Keys are in range set by combinations of ge, gt, le, and lt.
|
|
1542
1542
|
"""
|
|
1543
|
-
if ge and gt:
|
|
1543
|
+
if isinstance(ge, bytes) and isinstance(gt, bytes):
|
|
1544
1544
|
raise DatabaseError("Both 'ge' and 'gt' given in key range")
|
|
1545
|
-
if le and lt:
|
|
1545
|
+
if isinstance(le, bytes) and isinstance(lt, bytes):
|
|
1546
1546
|
raise DatabaseError("Both 'le' and 'lt' given in key range")
|
|
1547
1547
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1548
1548
|
with self.dbtxn.transaction.cursor(
|
|
@@ -1551,7 +1551,7 @@ class Database(_database.Database):
|
|
|
1551
1551
|
if ge is None and gt is None:
|
|
1552
1552
|
record = cursor.first()
|
|
1553
1553
|
else:
|
|
1554
|
-
record = cursor.set_range(ge or gt)
|
|
1554
|
+
record = cursor.set_range(ge or gt or b"")
|
|
1555
1555
|
if gt:
|
|
1556
1556
|
while record:
|
|
1557
1557
|
record = cursor.item()
|
|
@@ -611,10 +611,10 @@ class Database(_databasedu.Database):
|
|
|
611
611
|
new_segment = make_segment_from_item(item)
|
|
612
612
|
new_segment |= existing_segment
|
|
613
613
|
new_segment.normalize()
|
|
614
|
-
item[
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
614
|
+
item[-2] = (
|
|
615
|
+
self.database.encode_number_for_sequential_file_dump(
|
|
616
|
+
new_segment.count_records(), 2
|
|
617
|
+
)
|
|
618
618
|
)
|
|
619
619
|
if int.from_bytes(item[-2], byteorder="big") == 1:
|
|
620
620
|
item[-1] = write_segment_value(
|
|
@@ -108,9 +108,9 @@ class Database(_database.Database):
|
|
|
108
108
|
continue
|
|
109
109
|
for fieldattr in NOSQL_FIELDATTS:
|
|
110
110
|
if fieldattr not in filedesc[FIELDS][fieldname]:
|
|
111
|
-
filedesc[FIELDS][fieldname][
|
|
112
|
-
fieldattr
|
|
113
|
-
|
|
111
|
+
filedesc[FIELDS][fieldname][fieldattr] = (
|
|
112
|
+
SECONDARY_FIELDATTS[fieldattr]
|
|
113
|
+
)
|
|
114
114
|
self.specification = specification
|
|
115
115
|
self.segment_size_bytes = segment_size_bytes
|
|
116
116
|
self.dbenv = None
|
|
@@ -1229,7 +1229,7 @@ class Database(_database.Database):
|
|
|
1229
1229
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1230
1230
|
if keylike is None:
|
|
1231
1231
|
return recordlist
|
|
1232
|
-
matcher = re.compile(
|
|
1232
|
+
matcher = re.compile(keylike)
|
|
1233
1233
|
db = self.dbenv
|
|
1234
1234
|
fieldtree = self.trees[SUBFILE_DELIMITER.join((file, field))]
|
|
1235
1235
|
cursor = tree.Cursor(fieldtree)
|
|
@@ -1238,7 +1238,7 @@ class Database(_database.Database):
|
|
|
1238
1238
|
k = cursor.next()
|
|
1239
1239
|
if k is None:
|
|
1240
1240
|
break
|
|
1241
|
-
if not matcher.
|
|
1241
|
+
if not matcher.search(k):
|
|
1242
1242
|
continue
|
|
1243
1243
|
self.populate_recordset(
|
|
1244
1244
|
recordlist,
|
|
@@ -1322,9 +1322,9 @@ class Database(_database.Database):
|
|
|
1322
1322
|
("'", field, "' field in '", file, "' file is not ordered")
|
|
1323
1323
|
)
|
|
1324
1324
|
)
|
|
1325
|
-
if ge and gt:
|
|
1325
|
+
if isinstance(ge, str) and isinstance(gt, str):
|
|
1326
1326
|
raise DatabaseError("Both 'ge' and 'gt' given in key range")
|
|
1327
|
-
if le and lt:
|
|
1327
|
+
if isinstance(le, str) and isinstance(lt, str):
|
|
1328
1328
|
raise DatabaseError("Both 'le' and 'lt' given in key range")
|
|
1329
1329
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1330
1330
|
db = self.dbenv
|
|
@@ -1334,7 +1334,7 @@ class Database(_database.Database):
|
|
|
1334
1334
|
if ge is None and gt is None:
|
|
1335
1335
|
k = cursor.first()
|
|
1336
1336
|
else:
|
|
1337
|
-
k = cursor.nearest(ge or gt)
|
|
1337
|
+
k = cursor.nearest(ge or gt or "")
|
|
1338
1338
|
if gt:
|
|
1339
1339
|
while k is not None:
|
|
1340
1340
|
if k > gt:
|
|
@@ -121,9 +121,9 @@ class Database(_databasedu.Database):
|
|
|
121
121
|
ebmc = self.ebm_control[file]
|
|
122
122
|
tes = ebmc.table_ebm_segments
|
|
123
123
|
insertion_point = bisect_right(tes, segment)
|
|
124
|
-
self.dbenv[
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
self.dbenv[SUBFILE_DELIMITER.join((ebmc.ebm_table, str(segment)))] = (
|
|
125
|
+
repr(self.existence_bit_maps[file][segment].tobytes())
|
|
126
|
+
)
|
|
127
127
|
if not (tes and tes[insertion_point - 1] == segment):
|
|
128
128
|
tes.insert(insertion_point, segment)
|
|
129
129
|
self.dbenv[ebmc.ebm_table] = repr(tes)
|
|
@@ -991,9 +991,12 @@ class Database(_database.Database):
|
|
|
991
991
|
update_count_and_reference,
|
|
992
992
|
(
|
|
993
993
|
count,
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
994
|
+
(
|
|
995
|
+
record_number
|
|
996
|
+
% (segment * SegmentSize.db_segment_size)
|
|
997
|
+
if segment
|
|
998
|
+
else record_number
|
|
999
|
+
),
|
|
997
1000
|
key,
|
|
998
1001
|
segment,
|
|
999
1002
|
),
|
|
@@ -1488,12 +1491,12 @@ class Database(_database.Database):
|
|
|
1488
1491
|
)
|
|
1489
1492
|
)
|
|
1490
1493
|
db_segment_size_bytes = SegmentSize.db_segment_size_bytes
|
|
1491
|
-
matcher = re.compile(
|
|
1494
|
+
matcher = re.compile(keylike)
|
|
1492
1495
|
get_segment_records = self.get_segment_records
|
|
1493
1496
|
cursor = self.dbenv.cursor()
|
|
1494
1497
|
try:
|
|
1495
1498
|
for record in cursor.execute(statement):
|
|
1496
|
-
if not matcher.
|
|
1499
|
+
if not matcher.search(record[0]):
|
|
1497
1500
|
continue
|
|
1498
1501
|
if record[2] == 1:
|
|
1499
1502
|
segment = RecordsetSegmentInt(
|
|
@@ -1595,9 +1598,11 @@ class Database(_database.Database):
|
|
|
1595
1598
|
values = (
|
|
1596
1599
|
b"".join(
|
|
1597
1600
|
(
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
+
(
|
|
1602
|
+
keystart.encode()
|
|
1603
|
+
if isinstance(keystart, str)
|
|
1604
|
+
else keystart
|
|
1605
|
+
),
|
|
1601
1606
|
b"*",
|
|
1602
1607
|
)
|
|
1603
1608
|
),
|
|
@@ -1638,14 +1643,22 @@ class Database(_database.Database):
|
|
|
1638
1643
|
|
|
1639
1644
|
Keys are in range set by combinations of ge, gt, le, and lt.
|
|
1640
1645
|
"""
|
|
1641
|
-
if ge and gt:
|
|
1646
|
+
if isinstance(ge, str) and isinstance(gt, str):
|
|
1642
1647
|
raise DatabaseError("Both 'ge' and 'gt' given in key range")
|
|
1643
|
-
if le and lt:
|
|
1648
|
+
if isinstance(le, str) and isinstance(lt, str):
|
|
1644
1649
|
raise DatabaseError("Both 'le' and 'lt' given in key range")
|
|
1645
1650
|
if ge is None and gt is None and le is None and lt is None:
|
|
1646
1651
|
return self.recordlist_all(file, field, cache_size=cache_size)
|
|
1647
|
-
highop =
|
|
1648
|
-
|
|
1652
|
+
highop = (
|
|
1653
|
+
"<"
|
|
1654
|
+
if isinstance(lt, str)
|
|
1655
|
+
else "<=" if isinstance(le, str) else None
|
|
1656
|
+
)
|
|
1657
|
+
lowop = (
|
|
1658
|
+
">"
|
|
1659
|
+
if isinstance(gt, str)
|
|
1660
|
+
else ">=" if isinstance(ge, str) else None
|
|
1661
|
+
)
|
|
1649
1662
|
recordlist = RecordList(dbhome=self, dbset=file, cache_size=cache_size)
|
|
1650
1663
|
if highop is None:
|
|
1651
1664
|
statement = " ".join(
|
|
@@ -1666,7 +1679,7 @@ class Database(_database.Database):
|
|
|
1666
1679
|
"?",
|
|
1667
1680
|
)
|
|
1668
1681
|
)
|
|
1669
|
-
values = (ge or gt,)
|
|
1682
|
+
values = (ge or gt or "",)
|
|
1670
1683
|
elif lowop is None:
|
|
1671
1684
|
statement = " ".join(
|
|
1672
1685
|
(
|
|
@@ -1686,7 +1699,7 @@ class Database(_database.Database):
|
|
|
1686
1699
|
"?",
|
|
1687
1700
|
)
|
|
1688
1701
|
)
|
|
1689
|
-
values = (le or lt,)
|
|
1702
|
+
values = (le or lt or "",)
|
|
1690
1703
|
else:
|
|
1691
1704
|
statement = " ".join(
|
|
1692
1705
|
(
|
|
@@ -1709,7 +1722,7 @@ class Database(_database.Database):
|
|
|
1709
1722
|
"?",
|
|
1710
1723
|
)
|
|
1711
1724
|
)
|
|
1712
|
-
values = ge or gt, le or lt
|
|
1725
|
+
values = (ge or gt or "", le or lt or "")
|
|
1713
1726
|
db_segment_size_bytes = SegmentSize.db_segment_size_bytes
|
|
1714
1727
|
get_segment_records = self.get_segment_records
|
|
1715
1728
|
cursor = self.dbenv.cursor()
|
|
@@ -152,8 +152,10 @@ class Find:
|
|
|
152
152
|
for segment in recordset.rs_segments.values():
|
|
153
153
|
j = segment.first()
|
|
154
154
|
while j:
|
|
155
|
-
instance.load_record(
|
|
156
|
-
|
|
155
|
+
instance.load_record(
|
|
156
|
+
self._db.get_primary_record(self._dbset, j[1])
|
|
157
|
+
)
|
|
158
|
+
yield j[1], instance.value
|
|
157
159
|
j = segment.next()
|
|
158
160
|
|
|
159
161
|
def non_index_condition(self, obj, record_number, record):
|
|
@@ -547,9 +547,11 @@ class Record:
|
|
|
547
547
|
record = database.get_primary_record(
|
|
548
548
|
dbset,
|
|
549
549
|
# database.decode_as_primary_key(dbset, newrecord.srkey))
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
550
|
+
(
|
|
551
|
+
database.decode_record_number(newrecord.srkey)
|
|
552
|
+
if isinstance(newrecord.srkey, int)
|
|
553
|
+
else newrecord.srkey
|
|
554
|
+
),
|
|
553
555
|
)
|
|
554
556
|
if record is None:
|
|
555
557
|
database.put_instance(dbset, newrecord)
|
|
@@ -36,13 +36,12 @@ particularly the last of these.
|
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
38
|
import re
|
|
39
|
-
import sre_constants
|
|
40
39
|
from tkinter import simpledialog
|
|
41
40
|
|
|
42
41
|
from .constants import SECONDARY
|
|
43
42
|
|
|
44
|
-
DOUBLE_QUOTE_STRING = '"
|
|
45
|
-
SINGLE_QUOTE_STRING = "'
|
|
43
|
+
DOUBLE_QUOTE_STRING = r'"[^\\"]*(?:\\.[^\\"]*)*"'
|
|
44
|
+
SINGLE_QUOTE_STRING = r"'[^\\']*(?:\\.[^\\']*)*'"
|
|
46
45
|
LEFT_PARENTHESIS = "("
|
|
47
46
|
RIGHT_PARENTHESIS = ")"
|
|
48
47
|
OR = "or"
|
|
@@ -67,7 +66,7 @@ BELOW = "below"
|
|
|
67
66
|
BEFORE = "before"
|
|
68
67
|
STARTS = "starts"
|
|
69
68
|
PRESENT = "present"
|
|
70
|
-
STRING = "
|
|
69
|
+
STRING = r"\w+|\s+|[^\w\s()'\"]+|['\"]"
|
|
71
70
|
|
|
72
71
|
LEADING_SPACE = r"(?<=\s)"
|
|
73
72
|
TRAILING_SPACE = r"(?=\s)"
|
|
@@ -102,9 +101,9 @@ WHERE_RE = re.compile(
|
|
|
102
101
|
BEFORE.join((LEADING_SPACE, TRAILING_SPACE)),
|
|
103
102
|
STARTS.join((LEADING_SPACE, TRAILING_SPACE)),
|
|
104
103
|
PRESENT.join((LEADING_SPACE, r"(?=\s|\)|\Z)")),
|
|
105
|
-
STRING,
|
|
104
|
+
STRING.join("()"),
|
|
106
105
|
)
|
|
107
|
-
)
|
|
106
|
+
),
|
|
108
107
|
flags=re.IGNORECASE | re.DOTALL,
|
|
109
108
|
)
|
|
110
109
|
|
|
@@ -175,26 +174,41 @@ class Where:
|
|
|
175
174
|
def lex(self):
|
|
176
175
|
"""Split instance's statement into tokens."""
|
|
177
176
|
tokens = []
|
|
177
|
+
items = []
|
|
178
178
|
strings = []
|
|
179
|
-
|
|
179
|
+
string_items = []
|
|
180
|
+
for item in WHERE_RE.finditer(self.statement):
|
|
181
|
+
word = item.group()
|
|
180
182
|
if word.lower() in KEYWORDS:
|
|
181
183
|
if strings:
|
|
182
|
-
tokens.append("".join(
|
|
184
|
+
tokens.append("".join(_trim(strings)))
|
|
183
185
|
strings.clear()
|
|
186
|
+
items.append(tuple(string_items))
|
|
187
|
+
string_items.clear()
|
|
184
188
|
tokens.append(word.lower())
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
items.append((item,))
|
|
190
|
+
elif word:
|
|
191
|
+
strings.append(word)
|
|
192
|
+
string_items.append(item)
|
|
187
193
|
if strings:
|
|
188
|
-
tokens.append("".join(
|
|
194
|
+
tokens.append("".join(_trim(strings)))
|
|
189
195
|
strings.clear()
|
|
190
|
-
|
|
196
|
+
items.append(tuple(string_items))
|
|
197
|
+
string_items.clear()
|
|
198
|
+
self.tokens = [
|
|
199
|
+
(i, t)
|
|
200
|
+
for i, t in zip(items, tokens)
|
|
201
|
+
if t != "" or None in [j.group(1) for j in i]
|
|
202
|
+
]
|
|
191
203
|
|
|
192
204
|
def parse(self):
|
|
193
205
|
"""Parse instance's tokens to create node structure to do query."""
|
|
194
206
|
self.node = WhereClause()
|
|
195
207
|
state = self._set_field_not_leftp_start
|
|
196
208
|
for i, token in enumerate(self.tokens):
|
|
197
|
-
state = state(token)
|
|
209
|
+
# May need to be 'state = state(token)' with the <state>
|
|
210
|
+
# methods influenced by token[0] if appropriate.
|
|
211
|
+
state = state(token[1])
|
|
198
212
|
if not state:
|
|
199
213
|
self._error_information.tokens = self.tokens[: i + 1]
|
|
200
214
|
break
|
|
@@ -392,10 +406,10 @@ class Where:
|
|
|
392
406
|
if token_lower == LEFT_PARENTHESIS:
|
|
393
407
|
self._first_token_left_parenthesis(token)
|
|
394
408
|
return self._set_field_not_leftp
|
|
395
|
-
if token_lower
|
|
396
|
-
self.
|
|
397
|
-
|
|
398
|
-
return self.
|
|
409
|
+
if token_lower in KEYWORDS:
|
|
410
|
+
self.raise_where_error(token)
|
|
411
|
+
self._first_token_field(token)
|
|
412
|
+
return self._set_not_num_alpha_condition
|
|
399
413
|
|
|
400
414
|
def _set_field_leftp(self, token):
|
|
401
415
|
"""Expect fieldname, or '(', after 'not'."""
|
|
@@ -403,11 +417,11 @@ class Where:
|
|
|
403
417
|
if token_lower == LEFT_PARENTHESIS:
|
|
404
418
|
self._boolean_left_parenthesis(token)
|
|
405
419
|
return self._set_field_not_leftp
|
|
406
|
-
if token_lower
|
|
407
|
-
self.
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
return self.
|
|
420
|
+
if token_lower in KEYWORDS:
|
|
421
|
+
self.raise_where_error(token)
|
|
422
|
+
self._deferred_not_phrase()
|
|
423
|
+
self.node.field = token
|
|
424
|
+
return self._set_not_num_alpha_condition
|
|
411
425
|
|
|
412
426
|
def _set_field_not_leftp(self, token):
|
|
413
427
|
"""Expect fieldname, 'not', or '(', after '(' or boolean."""
|
|
@@ -418,11 +432,11 @@ class Where:
|
|
|
418
432
|
if token_lower == LEFT_PARENTHESIS:
|
|
419
433
|
self._boolean_left_parenthesis(token)
|
|
420
434
|
return self._set_field_not_leftp
|
|
421
|
-
if token_lower
|
|
422
|
-
self.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
return self.
|
|
435
|
+
if token_lower in KEYWORDS:
|
|
436
|
+
self.raise_where_error(token)
|
|
437
|
+
self._deferred_not_phrase()
|
|
438
|
+
self.node.field = token
|
|
439
|
+
return self._set_not_num_alpha_condition
|
|
426
440
|
|
|
427
441
|
def _set_not_num_alpha_condition(self, token):
|
|
428
442
|
"""Expect 'not', 'num', 'alpha', or a condition, after fieldname."""
|
|
@@ -440,7 +454,7 @@ class Where:
|
|
|
440
454
|
# for the token_lower == NOT case because 'is' is never
|
|
441
455
|
# preceded by 'not'.
|
|
442
456
|
if self._not:
|
|
443
|
-
|
|
457
|
+
self.raise_where_error(token)
|
|
444
458
|
self.node.condition = token_lower
|
|
445
459
|
return self._set_not_value
|
|
446
460
|
|
|
@@ -473,7 +487,8 @@ class Where:
|
|
|
473
487
|
self._deferred_not_condition()
|
|
474
488
|
self.node.condition = token_lower
|
|
475
489
|
return self._set_first_value
|
|
476
|
-
|
|
490
|
+
self.raise_where_error(token)
|
|
491
|
+
return None
|
|
477
492
|
|
|
478
493
|
def _set_second_condition(self, token):
|
|
479
494
|
"""Expect second condition after first value of double condition."""
|
|
@@ -481,7 +496,8 @@ class Where:
|
|
|
481
496
|
if token_lower in SECOND_CONDITIONS:
|
|
482
497
|
self.node.condition = self.node.condition, token_lower
|
|
483
498
|
return self._set_second_value
|
|
484
|
-
|
|
499
|
+
self.raise_where_error(token)
|
|
500
|
+
return None
|
|
485
501
|
|
|
486
502
|
def _set_not_value(self, token):
|
|
487
503
|
"""Expect 'not', or a value, after a condition."""
|
|
@@ -493,39 +509,37 @@ class Where:
|
|
|
493
509
|
|
|
494
510
|
def _set_value(self, token):
|
|
495
511
|
"""Expect value after single condition."""
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
self.node.value = token
|
|
499
|
-
return self._set_and_or_nor_rightp__single_condition
|
|
500
|
-
return self.error(token)
|
|
512
|
+
self.node.value = token
|
|
513
|
+
return self._set_and_or_nor_rightp__single_condition
|
|
501
514
|
|
|
502
515
|
def _set_value_like(self, token):
|
|
503
516
|
"""Expect value, a regular expression, after like."""
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
517
|
+
try:
|
|
518
|
+
re.compile(token)
|
|
519
|
+
except re.error as exc:
|
|
520
|
+
raise WhereError(
|
|
521
|
+
"".join(
|
|
522
|
+
(
|
|
523
|
+
"Problem with 'like' argument\n\n'",
|
|
524
|
+
token,
|
|
525
|
+
"'\n\nThe reported regular expression ",
|
|
526
|
+
"error is\n\n",
|
|
527
|
+
str(exc),
|
|
528
|
+
)
|
|
529
|
+
)
|
|
530
|
+
) from exc
|
|
531
|
+
self.node.value = token
|
|
532
|
+
return self._set_and_or_nor_rightp__single_condition
|
|
513
533
|
|
|
514
534
|
def _set_first_value(self, token):
|
|
515
535
|
"""Expect first value after first condition in double condition."""
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
self.node.value = token
|
|
519
|
-
return self._set_second_condition
|
|
520
|
-
return self.error(token)
|
|
536
|
+
self.node.value = token
|
|
537
|
+
return self._set_second_condition
|
|
521
538
|
|
|
522
539
|
def _set_second_value(self, token):
|
|
523
540
|
"""Expect second value after second condition in double condition."""
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
self.node.value = self.node.value, token
|
|
527
|
-
return self._set_and_or_nor_rightp__single_condition
|
|
528
|
-
return self.error(token)
|
|
541
|
+
self.node.value = self.node.value, token
|
|
542
|
+
return self._set_and_or_nor_rightp__single_condition
|
|
529
543
|
|
|
530
544
|
def _set_and_or_nor_rightp__single_condition(self, token):
|
|
531
545
|
"""Expect boolean or rightp after value in single condition phrase.
|
|
@@ -589,7 +603,8 @@ class Where:
|
|
|
589
603
|
raise WhereError("No unmatched left-parentheses")
|
|
590
604
|
self.node = self.node.up
|
|
591
605
|
return self._set_and_or_nor_rightp
|
|
592
|
-
|
|
606
|
+
self.raise_where_error(token)
|
|
607
|
+
return None
|
|
593
608
|
|
|
594
609
|
def _set_field_leftp_not_condition(self, token):
|
|
595
610
|
"""Expect fieldname, '(', 'not', or condition after rightp."""
|
|
@@ -602,11 +617,11 @@ class Where:
|
|
|
602
617
|
def _set_field_leftp_condition(self, token):
|
|
603
618
|
"""Expect fieldname, '(', or condition after rightp 'not'."""
|
|
604
619
|
token_lower = token.lower()
|
|
605
|
-
if token_lower
|
|
606
|
-
self.
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
return self.
|
|
620
|
+
if token_lower in KEYWORDS:
|
|
621
|
+
return self._set_leftp_condition(token)
|
|
622
|
+
self._deferred_not_phrase()
|
|
623
|
+
self.node.field = token
|
|
624
|
+
return self._set_not_num_alpha_condition
|
|
610
625
|
|
|
611
626
|
def _set_field_leftp_not_condition_value(self, token):
|
|
612
627
|
"""Expect fieldname, '(', 'not', condition, or value, after rightp."""
|
|
@@ -619,10 +634,10 @@ class Where:
|
|
|
619
634
|
def _set_field_leftp_condition_value(self, token):
|
|
620
635
|
"""Expect fieldname, '(', condition, or value, after rightp 'not'."""
|
|
621
636
|
token_lower = token.lower()
|
|
622
|
-
if token_lower
|
|
623
|
-
self.
|
|
624
|
-
|
|
625
|
-
return self.
|
|
637
|
+
if token_lower in KEYWORDS:
|
|
638
|
+
return self._set_leftp_condition(token)
|
|
639
|
+
self._f_or_v = token
|
|
640
|
+
return self._set_field_or_value__not
|
|
626
641
|
|
|
627
642
|
def _set_field_or_value__not(self, token):
|
|
628
643
|
"""Expect keyword to interpret previous token as field or value."""
|
|
@@ -657,7 +672,7 @@ class Where:
|
|
|
657
672
|
# for the token_lower == NOT case because 'is' is never
|
|
658
673
|
# preceded by 'not'.
|
|
659
674
|
if self._not:
|
|
660
|
-
|
|
675
|
+
self.raise_where_error(token)
|
|
661
676
|
self._field_condition(token_lower)
|
|
662
677
|
return self._set_not_value
|
|
663
678
|
|
|
@@ -680,7 +695,8 @@ class Where:
|
|
|
680
695
|
self._field_condition(token_lower)
|
|
681
696
|
self._alphanum_condition(token_lower)
|
|
682
697
|
return self._set_condition
|
|
683
|
-
|
|
698
|
+
self.raise_where_error(token)
|
|
699
|
+
return None
|
|
684
700
|
|
|
685
701
|
# Why is this not the same as _set_num_alpha_condition?
|
|
686
702
|
# Perhaps the question should be the other way round!
|
|
@@ -699,7 +715,7 @@ class Where:
|
|
|
699
715
|
# for the token_lower == NOT case because 'is' is never
|
|
700
716
|
# preceded by 'not'.
|
|
701
717
|
if self._not:
|
|
702
|
-
|
|
718
|
+
self.raise_where_error(token)
|
|
703
719
|
self.node.condition = token_lower
|
|
704
720
|
return self._set_not_value
|
|
705
721
|
|
|
@@ -727,14 +743,12 @@ class Where:
|
|
|
727
743
|
self._copy_pre_alphanumeric()
|
|
728
744
|
self._alphanum_condition(token_lower)
|
|
729
745
|
return self._set_condition
|
|
730
|
-
|
|
746
|
+
self.raise_where_error(token)
|
|
747
|
+
return None
|
|
731
748
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
""
|
|
735
|
-
if token.lower() in KEYWORDS:
|
|
736
|
-
return False
|
|
737
|
-
return False
|
|
749
|
+
def raise_where_error(self, token):
|
|
750
|
+
"""Raise WhereError exception."""
|
|
751
|
+
raise WhereError(token.join(("Unable to process token '", "'")))
|
|
738
752
|
|
|
739
753
|
def _deferred_not_condition(self):
|
|
740
754
|
"""Nearest 'not' to left inverts a condition such as 'eq'."""
|
|
@@ -1112,15 +1126,18 @@ class WhereConstraint:
|
|
|
1112
1126
|
self.pending = False
|
|
1113
1127
|
|
|
1114
1128
|
|
|
1115
|
-
def _trim(
|
|
1116
|
-
"""Return
|
|
1129
|
+
def _trim(strings):
|
|
1130
|
+
"""Return trimmed copy of strings.
|
|
1117
1131
|
|
|
1118
|
-
The
|
|
1132
|
+
The first item has leading whitespace removed.
|
|
1133
|
+
The last item has trailing whitespace removed.
|
|
1134
|
+
One leading and one trailing ' or " is removed from all items longer
|
|
1135
|
+
than one character.
|
|
1119
1136
|
|
|
1120
1137
|
"""
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
return
|
|
1138
|
+
strings[0] = strings[0].lstrip()
|
|
1139
|
+
strings[-1] = strings[-1].rstrip()
|
|
1140
|
+
return [s[1:-1] if len(s) > 1 and s[0] in "'\"" else s for s in strings]
|
|
1124
1141
|
|
|
1125
1142
|
|
|
1126
1143
|
class WhereStatementError:
|
|
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 → solentware_base-5.2.1}/solentware_base/tools/berkeleydb_du_splice_fix.py
RENAMED
|
File without changes
|
{solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/compare_dpt_tape_files.py
RENAMED
|
File without changes
|
|
File without changes
|
{solentware-base-5.2 → solentware_base-5.2.1}/solentware_base/tools/sqlite_table_name_upgrade.py
RENAMED
|
File without changes
|
{solentware-base-5.2 → solentware_base-5.2.1}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|