sql-blocks 1.25.528999999999__py3-none-any.whl → 1.25.6109999999999__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 +80 -10
- {sql_blocks-1.25.528999999999.dist-info → sql_blocks-1.25.6109999999999.dist-info}/METADATA +1 -1
- sql_blocks-1.25.6109999999999.dist-info/RECORD +7 -0
- sql_blocks-1.25.528999999999.dist-info/RECORD +0 -7
- {sql_blocks-1.25.528999999999.dist-info → sql_blocks-1.25.6109999999999.dist-info}/LICENSE +0 -0
- {sql_blocks-1.25.528999999999.dist-info → sql_blocks-1.25.6109999999999.dist-info}/WHEEL +0 -0
- {sql_blocks-1.25.528999999999.dist-info → sql_blocks-1.25.6109999999999.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -84,6 +84,17 @@ class SQLObject:
|
|
84
84
|
appendix = {WHERE: r'\s+and\s+|', FROM: r'\s+join\s+|\s+JOIN\s+'}
|
85
85
|
return KEYWORD[key][0].format(appendix.get(key, ''))
|
86
86
|
|
87
|
+
@staticmethod
|
88
|
+
def contains_CASE_statement(text: str) -> bool:
|
89
|
+
return re.search(r'\bCASE\b', text, re.IGNORECASE)
|
90
|
+
|
91
|
+
@classmethod
|
92
|
+
def split_fields(cls, text: str, key: str) -> list:
|
93
|
+
if key == SELECT and cls.contains_CASE_statement(text):
|
94
|
+
return Case.parse(text)
|
95
|
+
separator = cls.get_separator(key)
|
96
|
+
return re.split(separator, text)
|
97
|
+
|
87
98
|
@staticmethod
|
88
99
|
def is_named_field(fld: str, name: str='') -> bool:
|
89
100
|
return re.search(fr'(\s+as\s+|\s+AS\s+){name}', fld)
|
@@ -103,6 +114,9 @@ class SQLObject:
|
|
103
114
|
result += re.split(r'([=()]|<>|\s+ON\s+|\s+on\s+)', fld)
|
104
115
|
return result
|
105
116
|
def cleanup(text: str) -> str:
|
117
|
+
# if re.search(r'^CASE\b', text):
|
118
|
+
if self.contains_CASE_statement(text):
|
119
|
+
return text
|
106
120
|
text = re.sub(r'[\n\t]', ' ', text)
|
107
121
|
if exact:
|
108
122
|
text = text.lower()
|
@@ -116,14 +130,13 @@ class SQLObject:
|
|
116
130
|
re.sub(pattern, '', cleanup(fld))
|
117
131
|
)
|
118
132
|
for string in disassemble(source)
|
119
|
-
for fld in
|
133
|
+
for fld in self.split_fields(string, key)
|
120
134
|
)
|
121
135
|
pattern = KEYWORD[key][1]
|
122
136
|
if exact:
|
123
137
|
if key == WHERE:
|
124
138
|
pattern = r'["\']| '
|
125
139
|
pattern += f'|{PATTERN_PREFIX}'
|
126
|
-
separator = self.get_separator(key)
|
127
140
|
s1 = field_set(search_list)
|
128
141
|
s2 = field_set(self.values.get(key, []))
|
129
142
|
if exact:
|
@@ -642,11 +655,19 @@ class Case:
|
|
642
655
|
self.__conditions = {}
|
643
656
|
self.default = None
|
644
657
|
self.field = field
|
658
|
+
self.current_condition = None
|
659
|
+
self.fields = []
|
645
660
|
|
646
|
-
def when(self, condition: Where, result):
|
661
|
+
def when(self, condition: Where, result=None):
|
662
|
+
self.current_condition = condition
|
663
|
+
if result is None:
|
664
|
+
return self
|
665
|
+
return self.then(result)
|
666
|
+
|
667
|
+
def then(self, result):
|
647
668
|
if isinstance(result, str):
|
648
669
|
result = quoted(result)
|
649
|
-
self.__conditions[result] =
|
670
|
+
self.__conditions[result] = self.current_condition
|
650
671
|
return self
|
651
672
|
|
652
673
|
def else_value(self, default):
|
@@ -655,17 +676,67 @@ class Case:
|
|
655
676
|
self.default = default
|
656
677
|
return self
|
657
678
|
|
658
|
-
def
|
659
|
-
field = Field.format(self.field, main)
|
679
|
+
def format(self, name: str, field: str='') -> str:
|
660
680
|
default = self.default
|
661
|
-
|
681
|
+
if not field:
|
682
|
+
field = self.field
|
683
|
+
return 'CASE \n{}\n\tEND AS {}'.format(
|
662
684
|
'\n'.join(
|
663
685
|
f'\t\tWHEN {field} {cond.content} THEN {res}'
|
664
686
|
for res, cond in self.__conditions.items()
|
665
687
|
) + (f'\n\t\tELSE {default}' if default else ''),
|
666
688
|
name
|
667
689
|
)
|
668
|
-
|
690
|
+
|
691
|
+
def add(self, name: str, main: SQLObject):
|
692
|
+
main.values.setdefault(SELECT, []).append(
|
693
|
+
self.format(
|
694
|
+
name, Field.format(self.field, main)
|
695
|
+
)
|
696
|
+
)
|
697
|
+
|
698
|
+
@classmethod
|
699
|
+
def parse(cls, expr: str) -> list:
|
700
|
+
result = []
|
701
|
+
block: 'Case' = None
|
702
|
+
# ---- functions of keywords: -----------------
|
703
|
+
def _when(word: str):
|
704
|
+
field, condition = word.split(' ', maxsplit=1)
|
705
|
+
condition = Where(condition)
|
706
|
+
if not block:
|
707
|
+
return cls(field).when(condition)
|
708
|
+
return block.when(condition)
|
709
|
+
def _then(word: str):
|
710
|
+
return block.then( eval(word) )
|
711
|
+
def _else(word: str):
|
712
|
+
return block.else_value( eval(word) )
|
713
|
+
def _end(word: str):
|
714
|
+
name, *rest = [t.strip() for t in re.split(r'\s+AS\s+|[,]', word) if t]
|
715
|
+
block.fields.append(
|
716
|
+
block.format(name)
|
717
|
+
)
|
718
|
+
block.fields += rest
|
719
|
+
return block
|
720
|
+
# -------------------------------------------------
|
721
|
+
KEYWORDS = {
|
722
|
+
'WHEN': _when, 'THEN': _then,
|
723
|
+
'ELSE': _else, 'END': _end,
|
724
|
+
}
|
725
|
+
RESERVED_WORDS = ['CASE'] + list(KEYWORDS)
|
726
|
+
REGEX = '|'.join(fr'\b{word}\b' for word in RESERVED_WORDS)
|
727
|
+
expr = re.sub(r'\s+', ' ', expr)
|
728
|
+
tokens = [t for t in re.split(f'({REGEX})', expr) if t.strip()]
|
729
|
+
last_word = ''
|
730
|
+
while tokens:
|
731
|
+
word = tokens.pop(0)
|
732
|
+
if last_word in KEYWORDS:
|
733
|
+
block = KEYWORDS[last_word](word)
|
734
|
+
result += block.fields
|
735
|
+
block.fields = []
|
736
|
+
elif word not in RESERVED_WORDS:
|
737
|
+
result.append(word.replace(',', ''))
|
738
|
+
last_word = word
|
739
|
+
return result
|
669
740
|
|
670
741
|
|
671
742
|
class Options:
|
@@ -1353,13 +1424,12 @@ class SQLParser(Parser):
|
|
1353
1424
|
for key in USUAL_KEYS:
|
1354
1425
|
if not key in values:
|
1355
1426
|
continue
|
1356
|
-
separator = self.class_type.get_separator(key)
|
1357
1427
|
cls = {
|
1358
1428
|
ORDER_BY: OrderBy, GROUP_BY: GroupBy
|
1359
1429
|
}.get(key, Field)
|
1360
1430
|
obj.values[key] = [
|
1361
1431
|
cls.format(fld, obj)
|
1362
|
-
for fld in
|
1432
|
+
for fld in self.class_type.split_fields(values[key], key)
|
1363
1433
|
if (fld != '*' and len(tables) == 1) or obj.match(fld, key)
|
1364
1434
|
]
|
1365
1435
|
result[obj.alias] = obj
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 1.25.
|
3
|
+
Version: 1.25.6109999999999
|
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=09o87wu2xc82AMMyV-OBiYmv0d_kfL_DIH6G--3-DIA,71615
|
3
|
+
sql_blocks-1.25.6109999999999.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-1.25.6109999999999.dist-info/METADATA,sha256=KpFEm1tvvHvoURZ3kV1VjvBvSIEGGAWuskacBXg0Xp4,22236
|
5
|
+
sql_blocks-1.25.6109999999999.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-1.25.6109999999999.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-1.25.6109999999999.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
-
sql_blocks/sql_blocks.py,sha256=qhzO4tlxBE3dSqDZ-ow1b08H90xDytWXrFMrf6Y-5Og,69096
|
3
|
-
sql_blocks-1.25.528999999999.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
-
sql_blocks-1.25.528999999999.dist-info/METADATA,sha256=GNAFIVbNrBrijE1PbjoHaaPRIwrC_NbSLEd-VF0WWyc,22235
|
5
|
-
sql_blocks-1.25.528999999999.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
sql_blocks-1.25.528999999999.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
-
sql_blocks-1.25.528999999999.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{sql_blocks-1.25.528999999999.dist-info → sql_blocks-1.25.6109999999999.dist-info}/top_level.txt
RENAMED
File without changes
|