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 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(fld: str) -> str:
102
+ def cleanup(text: str) -> str:
103
+ text = re.sub(r'[\n\t]', ' ', text)
103
104
  if exact:
104
- fld = fld.lower()
105
- return fld.strip()
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
- main.values.setdefault(WHERE, []).append('({a1}.{f1} = {a2}.{f2})'.format(
601
- a1=main.alias, f1=name,
602
- a2=query.alias, f2=query.key_field
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
- conditions: list[str] = []
674
+ temp = Select(f'{main.table_name} {main.alias}')
673
675
  child: Where
674
676
  for field, child in self.__children.items():
675
- conditions.append(' {} {} '.format(
676
- Field.format(field, main), child.content
677
- ))
677
+ child.add(field, temp)
678
678
  main.values.setdefault(WHERE, []).append(
679
- '(' + logical_separator.join(conditions) + ')'
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(fld: str) -> str:
840
- return ''.join(re.split(r'\w+[.]', fld))
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.51999999999
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,,