sql-blocks 1.25.112__py3-none-any.whl → 1.25.113__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sql_blocks/sql_blocks.py +47 -19
- {sql_blocks-1.25.112.dist-info → sql_blocks-1.25.113.dist-info}/METADATA +1 -1
- sql_blocks-1.25.113.dist-info/RECORD +7 -0
- sql_blocks-1.25.112.dist-info/RECORD +0 -7
- {sql_blocks-1.25.112.dist-info → sql_blocks-1.25.113.dist-info}/LICENSE +0 -0
- {sql_blocks-1.25.112.dist-info → sql_blocks-1.25.113.dist-info}/WHEEL +0 -0
- {sql_blocks-1.25.112.dist-info → sql_blocks-1.25.113.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -70,6 +70,10 @@ class SQLObject:
|
|
70
70
|
appendix = {WHERE: r'\s+and\s+|', FROM: r'\s+join\s+|\s+JOIN\s+'}
|
71
71
|
return KEYWORD[key][0].format(appendix.get(key, ''))
|
72
72
|
|
73
|
+
@staticmethod
|
74
|
+
def is_named_field(fld: str, key: str) -> bool:
|
75
|
+
return key == SELECT and re.search(r'\s+as\s+|\s+AS\s+', fld)
|
76
|
+
|
73
77
|
def diff(self, key: str, search_list: list, exact: bool=False) -> set:
|
74
78
|
def disassemble(source: list) -> list:
|
75
79
|
if not exact:
|
@@ -82,12 +86,10 @@ class SQLObject:
|
|
82
86
|
if exact:
|
83
87
|
fld = fld.lower()
|
84
88
|
return fld.strip()
|
85
|
-
def is_named_field(fld: str) -> bool:
|
86
|
-
return key == SELECT and re.search(r'\s+as\s+|\s+AS\s+', fld)
|
87
89
|
def field_set(source: list) -> set:
|
88
90
|
return set(
|
89
91
|
(
|
90
|
-
fld if is_named_field(fld) else
|
92
|
+
fld if self.is_named_field(fld, key) else
|
91
93
|
re.sub(pattern, '', cleanup(fld))
|
92
94
|
)
|
93
95
|
for string in disassemble(source)
|
@@ -105,13 +107,16 @@ class SQLObject:
|
|
105
107
|
return s1.symmetric_difference(s2)
|
106
108
|
return s1 - s2
|
107
109
|
|
108
|
-
def delete(self, search: str, keys: list=USUAL_KEYS):
|
110
|
+
def delete(self, search: str, keys: list=USUAL_KEYS, exact: bool=False):
|
111
|
+
if exact:
|
112
|
+
not_match = lambda item: not re.search(fr'\w*[.]*{search}$', item)
|
113
|
+
else:
|
114
|
+
not_match = lambda item: search not in item
|
109
115
|
for key in keys:
|
110
|
-
|
111
|
-
|
112
|
-
if
|
113
|
-
|
114
|
-
self.values[key] = result
|
116
|
+
self.values[key] = [
|
117
|
+
item for item in self.values.get(key, [])
|
118
|
+
if not_match(item)
|
119
|
+
]
|
115
120
|
|
116
121
|
|
117
122
|
SQL_CONST_SYSDATE = 'SYSDATE'
|
@@ -961,7 +966,7 @@ class SQLParser(Parser):
|
|
961
966
|
obj.values[key] = [
|
962
967
|
Field.format(fld, obj)
|
963
968
|
for fld in re.split(separator, values[key])
|
964
|
-
if (fld != '*' and len(tables) == 1) or obj.match(fld)
|
969
|
+
if (fld != '*' and len(tables) == 1) or obj.match(fld, key)
|
965
970
|
]
|
966
971
|
result[obj.alias] = obj
|
967
972
|
self.queries = list( result.values() )
|
@@ -1026,8 +1031,9 @@ class CypherParser(Parser):
|
|
1026
1031
|
if func_name == 'count':
|
1027
1032
|
if not token:
|
1028
1033
|
token = 'count_1'
|
1029
|
-
|
1030
|
-
|
1034
|
+
pk_field = self.queries[-1].key_field or 'id'
|
1035
|
+
Count().As(token, extra_classes).add(pk_field, self.queries[-1])
|
1036
|
+
return
|
1031
1037
|
else:
|
1032
1038
|
FUNCTION_CLASS = {f.__name__.lower(): f for f in Function.__subclasses__()}
|
1033
1039
|
class_list = [ FUNCTION_CLASS[func_name] ]
|
@@ -1048,7 +1054,7 @@ class CypherParser(Parser):
|
|
1048
1054
|
if not last.values.get(SELECT):
|
1049
1055
|
raise IndexError(f'Primary Key not found for {last.table_name}.')
|
1050
1056
|
pk_field = last.values[SELECT][-1].split('.')[-1]
|
1051
|
-
last.delete(pk_field, [SELECT])
|
1057
|
+
last.delete(pk_field, [SELECT], exact=True)
|
1052
1058
|
if '{}' in token:
|
1053
1059
|
foreign_fld = token.format(
|
1054
1060
|
last.table_name.lower()
|
@@ -1063,12 +1069,11 @@ class CypherParser(Parser):
|
|
1063
1069
|
if fld not in curr.values.get(GROUP_BY, [])
|
1064
1070
|
]
|
1065
1071
|
foreign_fld = fields[0].split('.')[-1]
|
1066
|
-
curr.delete(foreign_fld, [SELECT])
|
1072
|
+
curr.delete(foreign_fld, [SELECT], exact=True)
|
1067
1073
|
if curr.join_type == JoinType.RIGHT:
|
1068
1074
|
pk_field, foreign_fld = foreign_fld, pk_field
|
1069
1075
|
if curr.join_type == JoinType.RIGHT:
|
1070
1076
|
curr, last = last, curr
|
1071
|
-
# pk_field, foreign_fld = foreign_fld, pk_field
|
1072
1077
|
k = ForeignKey.get_key(curr, last)
|
1073
1078
|
ForeignKey.references[k] = (foreign_fld, pk_field)
|
1074
1079
|
|
@@ -1309,8 +1314,17 @@ class Select(SQLObject):
|
|
1309
1314
|
self.values.setdefault(LIMIT, result)
|
1310
1315
|
return self
|
1311
1316
|
|
1312
|
-
def match(self,
|
1313
|
-
|
1317
|
+
def match(self, field: str, key: str) -> bool:
|
1318
|
+
'''
|
1319
|
+
Recognizes if the field is from the current table
|
1320
|
+
'''
|
1321
|
+
if key in (ORDER_BY, GROUP_BY) and '.' not in field:
|
1322
|
+
return any(
|
1323
|
+
self.is_named_field(fld, SELECT)
|
1324
|
+
for fld in self.values[SELECT]
|
1325
|
+
if field in fld
|
1326
|
+
)
|
1327
|
+
return re.findall(f'\b*{self.alias}[.]', field) != []
|
1314
1328
|
|
1315
1329
|
@classmethod
|
1316
1330
|
def parse(cls, txt: str, parser: Parser = SQLParser) -> list[SQLObject]:
|
@@ -1431,12 +1445,13 @@ class RuleReplaceJoinBySubselect(Rule):
|
|
1431
1445
|
more_relations = any([
|
1432
1446
|
ref[0] == query.table_name for ref in ForeignKey.references
|
1433
1447
|
])
|
1434
|
-
|
1448
|
+
keep_join = any([
|
1435
1449
|
len( query.values.get(SELECT, []) ) > 0,
|
1436
1450
|
len( query.values.get(WHERE, []) ) == 0,
|
1437
1451
|
not fk_field, more_relations
|
1438
1452
|
])
|
1439
|
-
if
|
1453
|
+
if keep_join:
|
1454
|
+
query.add(fk_field, main)
|
1440
1455
|
continue
|
1441
1456
|
query.__class__ = SubSelect
|
1442
1457
|
Field.add(primary_k, query)
|
@@ -1482,3 +1497,16 @@ def detect(text: str) -> Select:
|
|
1482
1497
|
return result
|
1483
1498
|
|
1484
1499
|
|
1500
|
+
if __name__ == '__main__':
|
1501
|
+
p, c, a = Select.parse('''
|
1502
|
+
Professor(?nome="Júlio Cascalles", id)
|
1503
|
+
<- Curso@disciplina(professor, aluno) ->
|
1504
|
+
Aluno(id ^count$qtd_alunos)
|
1505
|
+
''', CypherParser)
|
1506
|
+
query = p + c + a
|
1507
|
+
print('#######################################')
|
1508
|
+
print(query)
|
1509
|
+
print('***************************************')
|
1510
|
+
query.optimize([RuleReplaceJoinBySubselect])
|
1511
|
+
print(query)
|
1512
|
+
print('#######################################')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 1.25.
|
3
|
+
Version: 1.25.113
|
4
4
|
Summary: Allows you to create objects for parts of SQL query commands. Also to combine these objects by joining them, adding or removing parts...
|
5
5
|
Home-page: https://github.com/julio-cascalles/sql_blocks
|
6
6
|
Author: Júlio Cascalles
|
@@ -0,0 +1,7 @@
|
|
1
|
+
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
+
sql_blocks/sql_blocks.py,sha256=Saj3MqmF0OHY60bhc_aSl8fL-PhXM2apmiPiE6KspOc,50553
|
3
|
+
sql_blocks-1.25.113.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-1.25.113.dist-info/METADATA,sha256=td1IZl9O3m2U0rWFk6gyecqWnkr0cMDW94PfeqhzP8Y,14638
|
5
|
+
sql_blocks-1.25.113.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-1.25.113.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-1.25.113.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
-
sql_blocks/sql_blocks.py,sha256=X13qSCvVhu-BVXdUmqXi48Z7H4THBvXHrP5zw2Hm4wM,49491
|
3
|
-
sql_blocks-1.25.112.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
-
sql_blocks-1.25.112.dist-info/METADATA,sha256=npxMGB0xgAFt4J_IgoIaaWmVFcVoNu5lq3qnUAjhb-A,14638
|
5
|
-
sql_blocks-1.25.112.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
sql_blocks-1.25.112.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
-
sql_blocks-1.25.112.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|