sql-blocks 1.25.51999999999__py3-none-any.whl → 1.25.514999999999__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 +136 -17
- {sql_blocks-1.25.51999999999.dist-info → sql_blocks-1.25.514999999999.dist-info}/METADATA +1 -1
- sql_blocks-1.25.514999999999.dist-info/RECORD +7 -0
- sql_blocks-1.25.51999999999.dist-info/RECORD +0 -7
- {sql_blocks-1.25.51999999999.dist-info → sql_blocks-1.25.514999999999.dist-info}/LICENSE +0 -0
- {sql_blocks-1.25.51999999999.dist-info → sql_blocks-1.25.514999999999.dist-info}/WHEEL +0 -0
- {sql_blocks-1.25.51999999999.dist-info → sql_blocks-1.25.514999999999.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -99,10 +99,11 @@ class SQLObject:
|
|
99
99
|
for fld in source:
|
100
100
|
result += re.split(r'([=()]|<>|\s+ON\s+|\s+on\s+)', fld)
|
101
101
|
return result
|
102
|
-
def cleanup(
|
102
|
+
def cleanup(text: str) -> str:
|
103
|
+
text = re.sub(r'[\n\t]', ' ', text)
|
103
104
|
if exact:
|
104
|
-
|
105
|
-
return
|
105
|
+
text = text.lower()
|
106
|
+
return text.strip()
|
106
107
|
def field_set(source: list) -> set:
|
107
108
|
return set(
|
108
109
|
(
|
@@ -597,10 +598,11 @@ class Where:
|
|
597
598
|
main.values[FROM].append(f',{query.table_name} {query.alias}')
|
598
599
|
for key in USUAL_KEYS:
|
599
600
|
main.update_values(key, query.values.get(key, []))
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
601
|
+
if query.key_field:
|
602
|
+
main.values.setdefault(WHERE, []).append('({a1}.{f1} = {a2}.{f2})'.format(
|
603
|
+
a1=main.alias, f1=name,
|
604
|
+
a2=query.alias, f2=query.key_field
|
605
|
+
))
|
604
606
|
|
605
607
|
def add(self, name: str, main: SQLObject):
|
606
608
|
func_type = FUNCTION_CLASS.get(name.lower())
|
@@ -667,16 +669,14 @@ class Options:
|
|
667
669
|
self.__children: dict = values
|
668
670
|
|
669
671
|
def add(self, logical_separator: str, main: SQLObject):
|
670
|
-
if logical_separator not in ('AND', 'OR'):
|
672
|
+
if logical_separator.upper() not in ('AND', 'OR'):
|
671
673
|
raise ValueError('`logical_separator` must be AND or OR')
|
672
|
-
|
674
|
+
temp = Select(f'{main.table_name} {main.alias}')
|
673
675
|
child: Where
|
674
676
|
for field, child in self.__children.items():
|
675
|
-
|
676
|
-
Field.format(field, main), child.content
|
677
|
-
))
|
677
|
+
child.add(field, temp)
|
678
678
|
main.values.setdefault(WHERE, []).append(
|
679
|
-
'(' + logical_separator.join(
|
679
|
+
'(' + f'\n\t{logical_separator} '.join(temp.values[WHERE]) + ')'
|
680
680
|
)
|
681
681
|
|
682
682
|
|
@@ -836,8 +836,16 @@ class QueryLanguage:
|
|
836
836
|
has_default = {key: bool(key == SELECT) for key in KEYWORD}
|
837
837
|
|
838
838
|
@staticmethod
|
839
|
-
def remove_alias(
|
840
|
-
|
839
|
+
def remove_alias(text: str) -> str:
|
840
|
+
value, sep = '', ''
|
841
|
+
text = re.sub('[\n\t]', ' ', text)
|
842
|
+
if ':' in text:
|
843
|
+
text, value = text.split(':', maxsplit=1)
|
844
|
+
sep = ':'
|
845
|
+
return '{}{}{}'.format(
|
846
|
+
''.join(re.split(r'\w+[.]', text)),
|
847
|
+
sep, value.replace("'", '"')
|
848
|
+
)
|
841
849
|
|
842
850
|
def join_with_tabs(self, values: list, sep: str='') -> str:
|
843
851
|
sep = sep + self.TABULATION
|
@@ -905,7 +913,8 @@ class MongoDBLanguage(QueryLanguage):
|
|
905
913
|
LOGICAL_OP_TO_MONGO_FUNC = {
|
906
914
|
'>': '$gt', '>=': '$gte',
|
907
915
|
'<': '$lt', '<=': '$lte',
|
908
|
-
'=': '$eq', '<>': '$ne',
|
916
|
+
'=': '$eq', '<>': '$ne',
|
917
|
+
'like': '$regex', 'LIKE': '$regex',
|
909
918
|
}
|
910
919
|
OPERATORS = '|'.join(op for op in LOGICAL_OP_TO_MONGO_FUNC)
|
911
920
|
REGEX = {
|
@@ -958,7 +967,7 @@ class MongoDBLanguage(QueryLanguage):
|
|
958
967
|
field, *op, const = tokens
|
959
968
|
op = ''.join(op)
|
960
969
|
expr = '{begin}{op}:{const}{end}'.format(
|
961
|
-
begin='{', const=const, end='}',
|
970
|
+
begin='{', const=const.replace('%', '.*'), end='}',
|
962
971
|
op=cls.LOGICAL_OP_TO_MONGO_FUNC[op],
|
963
972
|
)
|
964
973
|
where_list.append(f'{field}:{expr}')
|
@@ -1067,6 +1076,55 @@ class Neo4JLanguage(QueryLanguage):
|
|
1067
1076
|
return ''
|
1068
1077
|
|
1069
1078
|
|
1079
|
+
class DatabricksLanguage(QueryLanguage):
|
1080
|
+
pattern = '{_from}{where}{group_by}{order_by}{select}{limit}'
|
1081
|
+
has_default = {key: bool(key == SELECT) for key in KEYWORD}
|
1082
|
+
|
1083
|
+
def __init__(self, target: 'Select'):
|
1084
|
+
super().__init__(target)
|
1085
|
+
self.aggregation_fields = []
|
1086
|
+
|
1087
|
+
def add_field(self, values: list) -> str:
|
1088
|
+
AGG_FUNCS = '|'.join(cls.__name__ for cls in Aggregate.__subclasses__())
|
1089
|
+
# --------------------------------------------------------------
|
1090
|
+
def is_agg_field(fld: str) -> bool:
|
1091
|
+
return re.findall(fr'({AGG_FUNCS})[(]', fld, re.IGNORECASE)
|
1092
|
+
# --------------------------------------------------------------
|
1093
|
+
new_values = []
|
1094
|
+
for val in values:
|
1095
|
+
if is_agg_field(val):
|
1096
|
+
self.aggregation_fields.append(val)
|
1097
|
+
else:
|
1098
|
+
new_values.append(val)
|
1099
|
+
values = new_values
|
1100
|
+
return super().add_field(values)
|
1101
|
+
|
1102
|
+
def prefix(self, key: str) -> str:
|
1103
|
+
def get_aggregate() -> str:
|
1104
|
+
return 'AGGREGATE {} '.format(
|
1105
|
+
','.join(self.aggregation_fields)
|
1106
|
+
)
|
1107
|
+
return '{}{}{}{}{}'.format(
|
1108
|
+
'|> ' if key != FROM else '',
|
1109
|
+
self.LINE_BREAK,
|
1110
|
+
get_aggregate() if key == GROUP_BY else '',
|
1111
|
+
key, self.TABULATION
|
1112
|
+
)
|
1113
|
+
|
1114
|
+
# def get_tables(self, values: list) -> str:
|
1115
|
+
# return self.join_with_tabs(values)
|
1116
|
+
|
1117
|
+
# def extract_conditions(self, values: list) -> str:
|
1118
|
+
# return self.join_with_tabs(values, ' AND ')
|
1119
|
+
|
1120
|
+
# def sort_by(self, values: list) -> str:
|
1121
|
+
# return self.join_with_tabs(values, ',')
|
1122
|
+
|
1123
|
+
def set_group(self, values: list) -> str:
|
1124
|
+
return self.join_with_tabs(values, ',')
|
1125
|
+
|
1126
|
+
|
1127
|
+
|
1070
1128
|
class Parser:
|
1071
1129
|
REGEX = {}
|
1072
1130
|
|
@@ -1422,7 +1480,18 @@ class MongoParser(Parser):
|
|
1422
1480
|
|
1423
1481
|
def begin_conditions(self, value: str):
|
1424
1482
|
self.where_list = {}
|
1483
|
+
self.field_method = self.first_ORfield
|
1425
1484
|
return Where
|
1485
|
+
|
1486
|
+
def first_ORfield(self, text: str):
|
1487
|
+
if text.startswith('$'):
|
1488
|
+
return
|
1489
|
+
found = re.search(r'\w+[:]', text)
|
1490
|
+
if not found:
|
1491
|
+
return
|
1492
|
+
self.field_method = None
|
1493
|
+
p1, p2 = found.span()
|
1494
|
+
self.last_field = text[p1: p2-1]
|
1426
1495
|
|
1427
1496
|
def increment_brackets(self, value: str):
|
1428
1497
|
self.brackets[value] += 1
|
@@ -1431,6 +1500,7 @@ class MongoParser(Parser):
|
|
1431
1500
|
self.method = self.new_query
|
1432
1501
|
self.last_field = ''
|
1433
1502
|
self.where_list = None
|
1503
|
+
self.field_method = None
|
1434
1504
|
self.PARAM_BY_FUNCTION = {
|
1435
1505
|
'find': Where, 'aggregate': GroupBy, 'sort': OrderBy
|
1436
1506
|
}
|
@@ -1460,6 +1530,8 @@ class MongoParser(Parser):
|
|
1460
1530
|
self.close_brackets(
|
1461
1531
|
BRACKET_PAIR[token]
|
1462
1532
|
)
|
1533
|
+
elif self.field_method:
|
1534
|
+
self.field_method(token)
|
1463
1535
|
self.method = self.TOKEN_METHODS.get(token)
|
1464
1536
|
# ----------------------------
|
1465
1537
|
|
@@ -1846,3 +1918,50 @@ def detect(text: str, join_queries: bool = True, format: str='') -> Select | lis
|
|
1846
1918
|
result += query
|
1847
1919
|
return result
|
1848
1920
|
# ===========================================================================================//
|
1921
|
+
|
1922
|
+
|
1923
|
+
if __name__ == "__main__":
|
1924
|
+
# def identifica_suspeitos() -> Select:
|
1925
|
+
# """Mostra quais pessoas tem caracteríosticas iguais à descrição do suspeito"""
|
1926
|
+
# Select.join_type = JoinType.LEFT
|
1927
|
+
# return Select(
|
1928
|
+
# 'Suspeito s', id=Field,
|
1929
|
+
# _=Where.join(
|
1930
|
+
# Select('Pessoa p',
|
1931
|
+
# OR=Options(
|
1932
|
+
# pessoa=Where('= s.id'),
|
1933
|
+
# altura=Where.formula('ABS(% - s.{f}) < 0.5'),
|
1934
|
+
# peso=Where.formula('ABS(% - s.{f}) < 0.5'),
|
1935
|
+
# cabelo=Where.formula('% = s.{f}'),
|
1936
|
+
# olhos=Where.formula('% = s.{f}'),
|
1937
|
+
# sexo=Where.formula('% = s.{f}'),
|
1938
|
+
# ),
|
1939
|
+
# nome=Field
|
1940
|
+
# )
|
1941
|
+
# )
|
1942
|
+
# )
|
1943
|
+
# query = identifica_suspeitos()
|
1944
|
+
# print('='*50)
|
1945
|
+
# print(query)
|
1946
|
+
# print('-'*50)
|
1947
|
+
script = '''
|
1948
|
+
db.people.find({
|
1949
|
+
{
|
1950
|
+
$or: [
|
1951
|
+
status:{$eq:"B"},
|
1952
|
+
age:{$lt:50}
|
1953
|
+
]
|
1954
|
+
},
|
1955
|
+
age:{$gte:18}, status:{$eq:"A"}
|
1956
|
+
},{
|
1957
|
+
name: 1, user_id: 1
|
1958
|
+
}).sort({
|
1959
|
+
'''
|
1960
|
+
print('='*50)
|
1961
|
+
q1 = Select.parse(script, MongoParser)[0]
|
1962
|
+
print(q1)
|
1963
|
+
print('-'*50)
|
1964
|
+
q2 = q1.translate_to(MongoDBLanguage)
|
1965
|
+
print(q2)
|
1966
|
+
# print('-'*50)
|
1967
|
+
print('='*50)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 1.25.
|
3
|
+
Version: 1.25.514999999999
|
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=8msHsR5Ttp8vpCJbhU7wd91IP-TboC0XAc1204kLKXE,65953
|
3
|
+
sql_blocks-1.25.514999999999.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-1.25.514999999999.dist-info/METADATA,sha256=vxHahM3KUO84oALwycgcIdR2szRmrKUo-9RjDZffWhk,22242
|
5
|
+
sql_blocks-1.25.514999999999.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-1.25.514999999999.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-1.25.514999999999.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
-
sql_blocks/sql_blocks.py,sha256=ZdCFtPShmn-nHrE2tpJCWMnJYmPsc742CIkrPc_hSs4,61854
|
3
|
-
sql_blocks-1.25.51999999999.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
-
sql_blocks-1.25.51999999999.dist-info/METADATA,sha256=ZK0V4KW5v8VtqFML82WFBbN_NpDN7iHbGjMo09fiRbc,22241
|
5
|
-
sql_blocks-1.25.51999999999.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
sql_blocks-1.25.51999999999.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
-
sql_blocks-1.25.51999999999.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{sql_blocks-1.25.51999999999.dist-info → sql_blocks-1.25.514999999999.dist-info}/top_level.txt
RENAMED
File without changes
|