sql-blocks 1.2025.625__py3-none-any.whl → 1.2025.628__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 +67 -21
- {sql_blocks-1.2025.625.dist-info → sql_blocks-1.2025.628.dist-info}/METADATA +1 -1
- sql_blocks-1.2025.628.dist-info/RECORD +7 -0
- sql_blocks-1.2025.625.dist-info/RECORD +0 -7
- {sql_blocks-1.2025.625.dist-info → sql_blocks-1.2025.628.dist-info}/LICENSE +0 -0
- {sql_blocks-1.2025.625.dist-info → sql_blocks-1.2025.628.dist-info}/WHEEL +0 -0
- {sql_blocks-1.2025.625.dist-info → sql_blocks-1.2025.628.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -330,16 +330,21 @@ class DateDiff(Function):
|
|
330
330
|
append_param = True
|
331
331
|
|
332
332
|
def __str__(self) -> str:
|
333
|
-
def is_field_or_func(
|
333
|
+
def is_field_or_func(obj) -> bool:
|
334
|
+
if not isinstance(obj, str):
|
335
|
+
return True
|
334
336
|
candidate = re.sub(
|
335
|
-
'[()]', '',
|
337
|
+
'[()]', '', obj.split('.')[-1]
|
336
338
|
)
|
339
|
+
print(f'---------------> #{candidate=}#')
|
337
340
|
return candidate.isidentifier()
|
341
|
+
self.params = [
|
342
|
+
p if is_field_or_func(p) else f"'{p}'"
|
343
|
+
for p in self.params
|
344
|
+
]
|
338
345
|
if self.dialect != Dialect.SQL_SERVER:
|
339
|
-
params = [str(p) for p in self.params]
|
340
346
|
return ' - '.join(
|
341
|
-
p
|
342
|
-
for p in params
|
347
|
+
str(p) for p in self.params
|
343
348
|
) # <==== Date subtract
|
344
349
|
return super().__str__()
|
345
350
|
|
@@ -654,6 +659,8 @@ class Not(Where):
|
|
654
659
|
|
655
660
|
|
656
661
|
class Case:
|
662
|
+
break_lines = True
|
663
|
+
|
657
664
|
def __init__(self, field: str):
|
658
665
|
self.__conditions = {}
|
659
666
|
self.default = None
|
@@ -680,16 +687,24 @@ class Case:
|
|
680
687
|
return self
|
681
688
|
|
682
689
|
def format(self, name: str, field: str='') -> str:
|
690
|
+
TABULATION = '\t\t' if self.break_lines else ' '
|
691
|
+
LINE_BREAK = '\n' if self.break_lines else ' '
|
683
692
|
default = self.default
|
684
693
|
if not field:
|
685
694
|
field = self.field
|
686
|
-
return 'CASE
|
687
|
-
|
688
|
-
|
695
|
+
return 'CASE{brk}{cond}{df}{tab}END{alias}'.format(
|
696
|
+
brk=LINE_BREAK,
|
697
|
+
cond=LINE_BREAK.join(
|
698
|
+
f'{TABULATION}WHEN {field} {cond.content} THEN {res}'
|
689
699
|
for res, cond in self.__conditions.items()
|
690
|
-
)
|
691
|
-
|
700
|
+
),
|
701
|
+
df=f'{LINE_BREAK}{TABULATION}ELSE {default}' if not default is None else '',
|
702
|
+
tab='\n\t' if self.break_lines else ' ',
|
703
|
+
alias=f' AS {name}' if name else ''
|
692
704
|
)
|
705
|
+
|
706
|
+
def __str__(self):
|
707
|
+
return self.format('', self.field)
|
693
708
|
|
694
709
|
def add(self, name: str, main: SQLObject):
|
695
710
|
main.values.setdefault(SELECT, []).append(
|
@@ -2009,7 +2024,7 @@ class CTE(Select):
|
|
2009
2024
|
# ---------------------------------------------------------
|
2010
2025
|
return 'WITH {}{} AS (\n {}\n){}'.format(
|
2011
2026
|
self.prefix, self.table_name,
|
2012
|
-
'\
|
2027
|
+
'\n\tUNION ALL\n '.join(
|
2013
2028
|
justify(q) for q in self.query_list
|
2014
2029
|
), super().__str__() if self.show_query else ''
|
2015
2030
|
)
|
@@ -2081,18 +2096,33 @@ class CTEFactory:
|
|
2081
2096
|
self.cte_list = [
|
2082
2097
|
CTE(alias, [
|
2083
2098
|
Select.parse(query)[0]
|
2099
|
+
for query in elements
|
2084
2100
|
])
|
2085
|
-
for alias,
|
2101
|
+
for alias, elements in summary.items()
|
2086
2102
|
]
|
2087
2103
|
|
2088
2104
|
def __str__(self):
|
2089
2105
|
CTE.show_query = False
|
2090
2106
|
lines = [str(cte) for cte in self.cte_list]
|
2091
|
-
|
2107
|
+
result = ',\n'.join(lines) + '\n' + str(self.main)
|
2108
|
+
CTE.show_query = True
|
2109
|
+
return result
|
2092
2110
|
|
2093
2111
|
@staticmethod
|
2094
|
-
def extract_subqueries(txt: str) -> dict:
|
2112
|
+
def extract_subqueries(txt: str) -> dict:
|
2095
2113
|
result = {}
|
2114
|
+
# ---------------------------------------------------
|
2115
|
+
def clean_subquery(source: list) -> str:
|
2116
|
+
while source:
|
2117
|
+
if source[0].upper() == 'SELECT':
|
2118
|
+
break
|
2119
|
+
word = source.pop(0)
|
2120
|
+
if word.upper() in ('FROM', 'JOIN'):
|
2121
|
+
result[MAIN_TAG] += f' {word}'
|
2122
|
+
return ' '.join(source)
|
2123
|
+
def balanced_parentheses(expr: str) -> bool:
|
2124
|
+
return expr.count('(') == expr.count(')')
|
2125
|
+
# ---------------------------------------------------
|
2096
2126
|
for found in re.finditer(r'(FROM|JOIN)\s*[(]\s*SELECT', txt, re.IGNORECASE):
|
2097
2127
|
start = found.start()
|
2098
2128
|
alias = ''
|
@@ -2102,16 +2132,23 @@ class CTEFactory:
|
|
2102
2132
|
if not found:
|
2103
2133
|
break
|
2104
2134
|
end = found.end() + pos
|
2105
|
-
|
2106
|
-
if
|
2107
|
-
|
2135
|
+
last = end
|
2136
|
+
if balanced_parentheses(txt[start: end]):
|
2137
|
+
pos += found.start()
|
2138
|
+
alias = re.findall(r'\s*(\w+)$', txt[pos: end])[0]
|
2139
|
+
end = pos
|
2108
2140
|
pos = end
|
2109
|
-
first_word = elements.pop(0)
|
2110
2141
|
if not result:
|
2111
2142
|
result[MAIN_TAG] = txt[:start]
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2143
|
+
query_list = [
|
2144
|
+
clean_subquery( expr.split() )
|
2145
|
+
for expr in re.split(
|
2146
|
+
r'\bUNION\b', txt[start: end], re.IGNORECASE
|
2147
|
+
)
|
2148
|
+
]
|
2149
|
+
result[MAIN_TAG] += f' {alias} {alias}'
|
2150
|
+
result[alias] = query_list
|
2151
|
+
result[MAIN_TAG] += txt[last:]
|
2115
2152
|
return result
|
2116
2153
|
|
2117
2154
|
|
@@ -2259,3 +2296,12 @@ def detect(text: str, join_queries: bool = True, format: str='') -> Select | lis
|
|
2259
2296
|
result += query
|
2260
2297
|
return result
|
2261
2298
|
# ===========================================================================================//
|
2299
|
+
|
2300
|
+
if __name__ == "__main__":
|
2301
|
+
|
2302
|
+
print(
|
2303
|
+
Select(
|
2304
|
+
'Emprestimo e',
|
2305
|
+
_=Sum(Case('atraso').when(gt(60), 25).when(lt(15), 5).else_value(10)).As('multa', OrderBy)
|
2306
|
+
)
|
2307
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 1.2025.
|
3
|
+
Version: 1.2025.628
|
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=gbihrdYwzwGUMDO2pXSeIOmxxaOX9A-hXoz-qZv_4Ls,78290
|
3
|
+
sql_blocks-1.2025.628.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-1.2025.628.dist-info/METADATA,sha256=mhDyYy5hxk3A-I7CKjekvhTBizZVXpkUA5RtKMHcIks,23328
|
5
|
+
sql_blocks-1.2025.628.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-1.2025.628.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-1.2025.628.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
-
sql_blocks/sql_blocks.py,sha256=J7zEJ5JNRxI3F-7TIypb0myb5OgdE5Stv4boZCTVBLM,76610
|
3
|
-
sql_blocks-1.2025.625.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
-
sql_blocks-1.2025.625.dist-info/METADATA,sha256=I6KTi5S_usvCjJEQl6lm8LG4DaxHhX0NlGRwhHpKBT8,23328
|
5
|
-
sql_blocks-1.2025.625.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
sql_blocks-1.2025.625.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
-
sql_blocks-1.2025.625.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|