sql-blocks 1.25.518999999999__py3-none-any.whl → 1.25.610999999999__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
@@ -103,10 +103,16 @@ class SQLObject:
103
103
  result += re.split(r'([=()]|<>|\s+ON\s+|\s+on\s+)', fld)
104
104
  return result
105
105
  def cleanup(text: str) -> str:
106
+ if re.search(r'^CASE\b', text):
107
+ return text
106
108
  text = re.sub(r'[\n\t]', ' ', text)
107
109
  if exact:
108
110
  text = text.lower()
109
111
  return text.strip()
112
+ def split_fields(text: str) -> list:
113
+ if key == SELECT:
114
+ return Case.parse(text)
115
+ return re.split(separator, text)
110
116
  def field_set(source: list) -> set:
111
117
  return set(
112
118
  (
@@ -116,7 +122,7 @@ class SQLObject:
116
122
  re.sub(pattern, '', cleanup(fld))
117
123
  )
118
124
  for string in disassemble(source)
119
- for fld in re.split(separator, string)
125
+ for fld in split_fields(string)
120
126
  )
121
127
  pattern = KEYWORD[key][1]
122
128
  if exact:
@@ -131,6 +137,7 @@ class SQLObject:
131
137
  return s1 - s2
132
138
 
133
139
  def delete(self, search: str, keys: list=USUAL_KEYS, exact: bool=False):
140
+ search = re.escape(search)
134
141
  if exact:
135
142
  not_match = lambda item: not re.search(fr'\w*[.]*{search}$', item)
136
143
  else:
@@ -641,11 +648,19 @@ class Case:
641
648
  self.__conditions = {}
642
649
  self.default = None
643
650
  self.field = field
651
+ self.current_condition = None
652
+ self.fields = []
644
653
 
645
- def when(self, condition: Where, result):
654
+ def when(self, condition: Where, result=None):
655
+ self.current_condition = condition
656
+ if result is None:
657
+ return self
658
+ return self.then(result)
659
+
660
+ def then(self, result):
646
661
  if isinstance(result, str):
647
662
  result = quoted(result)
648
- self.__conditions[result] = condition
663
+ self.__conditions[result] = self.current_condition
649
664
  return self
650
665
 
651
666
  def else_value(self, default):
@@ -654,17 +669,67 @@ class Case:
654
669
  self.default = default
655
670
  return self
656
671
 
657
- def add(self, name: str, main: SQLObject):
658
- field = Field.format(self.field, main)
672
+ def format(self, name: str, field: str='') -> str:
659
673
  default = self.default
660
- name = 'CASE \n{}\n\tEND AS {}'.format(
674
+ if not field:
675
+ field = self.field
676
+ return 'CASE \n{}\n\tEND AS {}'.format(
661
677
  '\n'.join(
662
678
  f'\t\tWHEN {field} {cond.content} THEN {res}'
663
679
  for res, cond in self.__conditions.items()
664
680
  ) + (f'\n\t\tELSE {default}' if default else ''),
665
681
  name
666
682
  )
667
- main.values.setdefault(SELECT, []).append(name)
683
+
684
+ def add(self, name: str, main: SQLObject):
685
+ main.values.setdefault(SELECT, []).append(
686
+ self.format(
687
+ name, Field.format(self.field, main)
688
+ )
689
+ )
690
+
691
+ @classmethod
692
+ def parse(cls, expr: str) -> list:
693
+ result = []
694
+ block: 'Case' = None
695
+ # ---- functions of keywords: -----------------
696
+ def _when(word: str):
697
+ field, condition = word.split(' ', maxsplit=1)
698
+ condition = Where(condition)
699
+ if not block:
700
+ return cls(field).when(condition)
701
+ return block.when(condition)
702
+ def _then(word: str):
703
+ return block.then( eval(word) )
704
+ def _else(word: str):
705
+ return block.else_value( eval(word) )
706
+ def _end(word: str):
707
+ name, *rest = [t.strip() for t in re.split(r'\s+AS\s+|[,]', word) if t]
708
+ block.fields.append(
709
+ block.format(name)
710
+ )
711
+ block.fields += rest
712
+ return block
713
+ # -------------------------------------------------
714
+ KEYWORDS = {
715
+ 'WHEN': _when, 'THEN': _then,
716
+ 'ELSE': _else, 'END': _end,
717
+ }
718
+ RESERVED_WORDS = ['CASE'] + list(KEYWORDS)
719
+ REGEX = '|'.join(fr'\b{word}\b' for word in RESERVED_WORDS)
720
+ expr = re.sub(r'\s+', ' ', expr)
721
+ tokens = [t for t in re.split(f'({REGEX})', expr) if t.strip()]
722
+ last_word = ''
723
+ while tokens:
724
+ word = tokens.pop(0)
725
+ if last_word in KEYWORDS:
726
+ block = KEYWORDS[last_word](word)
727
+ result += block.fields
728
+ block.fields = []
729
+ elif word not in RESERVED_WORDS:
730
+ result.append(word)
731
+ last_word = word
732
+ return result
668
733
 
669
734
 
670
735
  class Options:
@@ -1437,7 +1502,11 @@ class CypherParser(Parser):
1437
1502
  raise ValueError(f'Unknown function `{func_name}`.')
1438
1503
  if ':' in token:
1439
1504
  token, field_alias = token.split(':')
1440
- class_type = class_type().As(field_alias)
1505
+ if extra_classes == [OrderBy]:
1506
+ class_type = class_type().As(field_alias, OrderBy)
1507
+ extra_classes = []
1508
+ else:
1509
+ class_type = class_type().As(field_alias)
1441
1510
  class_list = [class_type]
1442
1511
  class_list += extra_classes
1443
1512
  FieldList(token, class_list).add('', self.queries[-1])
@@ -2043,20 +2112,3 @@ def detect(text: str, join_queries: bool = True, format: str='') -> Select | lis
2043
2112
  # ===========================================================================================//
2044
2113
 
2045
2114
 
2046
- if __name__ == "__main__":
2047
- query = detect("""
2048
- SELECT
2049
- e.gender, d.region,
2050
- Avg(e.age)
2051
- FROM
2052
- Employees e
2053
- JOIN Departments d ON (e.depto_id = d.id)
2054
- WHERE
2055
- e.name LIKE 'A%'
2056
- GROUP BY
2057
- e.gender, d.region
2058
- ORDER BY
2059
- d.region DESC
2060
- """)
2061
- PandasLanguage.file_extension = FileExtension.XLSX
2062
- print( query.translate_to(PandasLanguage) )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql_blocks
3
- Version: 1.25.518999999999
3
+ Version: 1.25.610999999999
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=tdfGConHw2iosex_BSXAWxYTGufPyOVMSTyi3g6gqpM,71400
3
+ sql_blocks-1.25.610999999999.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
+ sql_blocks-1.25.610999999999.dist-info/METADATA,sha256=09DIeKq_SinVNKt0OyYQQDOZ2_DDR6CmoP_n99t4ZXA,22235
5
+ sql_blocks-1.25.610999999999.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
+ sql_blocks-1.25.610999999999.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
+ sql_blocks-1.25.610999999999.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
- sql_blocks/sql_blocks.py,sha256=UOjajzxiH5_aS_P_Xr5hPYCxOl7W-vw2u4Jdjps7phw,69333
3
- sql_blocks-1.25.518999999999.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
- sql_blocks-1.25.518999999999.dist-info/METADATA,sha256=mnArOHyZC4RZFRliEmbybSiZaYz-4ciaSFNbHaODG-I,22235
5
- sql_blocks-1.25.518999999999.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- sql_blocks-1.25.518999999999.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
- sql_blocks-1.25.518999999999.dist-info/RECORD,,