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 +77 -25
- {sql_blocks-1.25.518999999999.dist-info → sql_blocks-1.25.610999999999.dist-info}/METADATA +1 -1
- sql_blocks-1.25.610999999999.dist-info/RECORD +7 -0
- sql_blocks-1.25.518999999999.dist-info/RECORD +0 -7
- {sql_blocks-1.25.518999999999.dist-info → sql_blocks-1.25.610999999999.dist-info}/LICENSE +0 -0
- {sql_blocks-1.25.518999999999.dist-info → sql_blocks-1.25.610999999999.dist-info}/WHEEL +0 -0
- {sql_blocks-1.25.518999999999.dist-info → sql_blocks-1.25.610999999999.dist-info}/top_level.txt +0 -0
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
|
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] =
|
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
|
658
|
-
field = Field.format(self.field, main)
|
672
|
+
def format(self, name: str, field: str='') -> str:
|
659
673
|
default = self.default
|
660
|
-
|
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
|
-
|
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
|
-
|
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.
|
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,,
|
File without changes
|
File without changes
|
{sql_blocks-1.25.518999999999.dist-info → sql_blocks-1.25.610999999999.dist-info}/top_level.txt
RENAMED
File without changes
|