sql-blocks 1.20250710__py3-none-any.whl → 1.20250711__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 +74 -53
- {sql_blocks-1.20250710.dist-info → sql_blocks-1.20250711.dist-info}/METADATA +1 -1
- sql_blocks-1.20250711.dist-info/RECORD +7 -0
- sql_blocks-1.20250710.dist-info/RECORD +0 -7
- {sql_blocks-1.20250710.dist-info → sql_blocks-1.20250711.dist-info}/LICENSE +0 -0
- {sql_blocks-1.20250710.dist-info → sql_blocks-1.20250711.dist-info}/WHEEL +0 -0
- {sql_blocks-1.20250710.dist-info → sql_blocks-1.20250711.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -221,11 +221,12 @@ class Code:
|
|
221
221
|
def As(self, field_alias: str, modifiers=None):
|
222
222
|
if modifiers:
|
223
223
|
self.extra[field_alias] = TO_LIST(modifiers)
|
224
|
-
|
224
|
+
if field_alias:
|
225
|
+
self.field_class = NamedField(field_alias)
|
225
226
|
return self
|
226
227
|
|
227
228
|
def format(self, name: str, main: SQLObject) -> str:
|
228
|
-
|
229
|
+
return Field.format(name, main)
|
229
230
|
|
230
231
|
def __add(self, name: str, main: SQLObject):
|
231
232
|
name = self.format(name, main)
|
@@ -1674,38 +1675,51 @@ class CypherParser(Parser):
|
|
1674
1675
|
Where(' '.join(condition)).add(field, query)
|
1675
1676
|
|
1676
1677
|
def add_order(self, token: str):
|
1677
|
-
self.add_field(token,
|
1678
|
+
self.add_field(token, sorted=True)
|
1678
1679
|
|
1679
|
-
def add_field(self, token: str,
|
1680
|
+
def add_field(self, token: str, sorted: bool = False):
|
1680
1681
|
if token in self.TOKEN_METHODS:
|
1681
1682
|
return
|
1682
|
-
class_list = [Field]
|
1683
1683
|
if '*' in token:
|
1684
1684
|
token = token.replace('*', '')
|
1685
1685
|
self.queries[-1].key_field = token
|
1686
1686
|
return
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1687
|
+
# -------------------------------------------------------
|
1688
|
+
def field_params() -> dict:
|
1689
|
+
ROLE_OF_SEPARATOR = {
|
1690
|
+
'$': 'function',
|
1691
|
+
':': 'alias',
|
1692
|
+
'@': 'group',
|
1693
|
+
'!': 'field',
|
1694
|
+
}
|
1695
|
+
REGEX_FIELD = r'([{}])'.format(''.join(ROLE_OF_SEPARATOR))
|
1696
|
+
elements = re.split(REGEX_FIELD, token+'!')
|
1697
|
+
return {
|
1698
|
+
ROLE_OF_SEPARATOR[k]: v
|
1699
|
+
for k, v in zip(elements[1::2], elements[::2])
|
1700
|
+
}
|
1701
|
+
def run(function: str='', alias: str='', group: str='', field: str=''):
|
1702
|
+
is_count = function == 'count'
|
1703
|
+
if alias or is_count:
|
1704
|
+
field, alias = alias, field
|
1705
|
+
extra_classes = [OrderBy] if sorted else []
|
1706
|
+
if group:
|
1707
|
+
if not field:
|
1708
|
+
field = group
|
1709
|
+
extra_classes += [GroupBy]
|
1710
|
+
if function:
|
1711
|
+
if is_count and not field:
|
1712
|
+
field = self.queries[-1].key_field or 'id'
|
1713
|
+
class_type = FUNCTION_CLASS.get(function)
|
1697
1714
|
if not class_type:
|
1698
|
-
raise ValueError(f'Unknown function `{
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
class_list = [class_type]
|
1707
|
-
class_list += extra_classes
|
1708
|
-
FieldList(token, class_list).add('', self.queries[-1])
|
1715
|
+
raise ValueError(f'Unknown function `{function}`.')
|
1716
|
+
class_list = [ class_type().As(alias or group, extra_classes) ]
|
1717
|
+
else:
|
1718
|
+
class_list = [Field] + extra_classes
|
1719
|
+
FieldList(field, class_list).add('', self.queries[-1])
|
1720
|
+
# -------------------------------------------------------
|
1721
|
+
run( **field_params() )
|
1722
|
+
# -------------------------------------------------------
|
1709
1723
|
|
1710
1724
|
def left_ftable(self, token: str):
|
1711
1725
|
if self.queries:
|
@@ -2117,7 +2131,7 @@ class CTE(Select):
|
|
2117
2131
|
else:
|
2118
2132
|
count = len(fields)
|
2119
2133
|
queries = detect(
|
2120
|
-
pattern*count,
|
2134
|
+
pattern*count, join_method=None, format=format
|
2121
2135
|
)
|
2122
2136
|
FieldList(fields, queries, ziped=True).add('', self)
|
2123
2137
|
self.break_lines = True
|
@@ -2138,7 +2152,7 @@ class Recursive(CTE):
|
|
2138
2152
|
def get_field(obj: SQLObject, pos: int) -> str:
|
2139
2153
|
return obj.values[SELECT][pos].split('.')[-1]
|
2140
2154
|
t1, t2 = detect(
|
2141
|
-
pattern*2,
|
2155
|
+
pattern*2, join_method=None, format=format
|
2142
2156
|
)
|
2143
2157
|
pk_field = get_field(t1, 0)
|
2144
2158
|
foreign_key = ''
|
@@ -2173,6 +2187,14 @@ class CTEFactory:
|
|
2173
2187
|
FROM** ( `sub_query1` ) **AS** `alias_1`
|
2174
2188
|
JOIN ( `sub_query2` ) **AS** `alias_2` **ON** `__join__`
|
2175
2189
|
"""
|
2190
|
+
if parser_class(txt) == CypherParser:
|
2191
|
+
query_list = Select.parse(txt, CypherParser)
|
2192
|
+
alias = '_'.join(query.table_name for query in query_list)
|
2193
|
+
self.main = Select(alias)
|
2194
|
+
self.main.break_lines = False
|
2195
|
+
query = join_queries(query_list)
|
2196
|
+
self.cte_list = [CTE(alias, [query])]
|
2197
|
+
return
|
2176
2198
|
summary = self.extract_subqueries(txt)
|
2177
2199
|
self.main = detect( summary.pop(MAIN_TAG) )
|
2178
2200
|
self.cte_list = [
|
@@ -2351,8 +2373,13 @@ def parser_class(text: str) -> Parser:
|
|
2351
2373
|
return class_type
|
2352
2374
|
return None
|
2353
2375
|
|
2376
|
+
def join_queries(query_list: list) -> Select:
|
2377
|
+
result = query_list[0]
|
2378
|
+
for query in query_list[1:]:
|
2379
|
+
result += query
|
2380
|
+
return result
|
2354
2381
|
|
2355
|
-
def detect(text: str,
|
2382
|
+
def detect(text: str, join_method = join_queries, format: str='') -> Select | list[Select]:
|
2356
2383
|
from collections import Counter
|
2357
2384
|
parser = parser_class(text)
|
2358
2385
|
if not parser:
|
@@ -2367,34 +2394,28 @@ def detect(text: str, join_queries: bool = True, format: str='') -> Select | lis
|
|
2367
2394
|
Select.EQUIVALENT_NAMES[new_name] = table
|
2368
2395
|
text = text[:begin] + new_name + '(' + text[end:]
|
2369
2396
|
count -= 1
|
2370
|
-
|
2397
|
+
result = Select.parse(text, parser)
|
2371
2398
|
if format:
|
2372
|
-
for query in
|
2399
|
+
for query in result:
|
2373
2400
|
query.set_file_format(format)
|
2374
|
-
if
|
2375
|
-
|
2376
|
-
result = query_list[0]
|
2377
|
-
for query in query_list[1:]:
|
2378
|
-
result += query
|
2401
|
+
if join_method:
|
2402
|
+
result = join_method(result)
|
2379
2403
|
return result
|
2380
2404
|
# ===========================================================================================//
|
2381
2405
|
|
2382
2406
|
if __name__ == "__main__":
|
2383
|
-
|
2384
|
-
|
2385
|
-
|
2386
|
-
|
2387
|
-
|
2388
|
-
|
2389
|
-
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2393
|
-
|
2394
|
-
|
2395
|
-
|
2396
|
-
prod_id='product', ref_year='year', vendor_id='vendor'
|
2397
|
-
)
|
2398
|
-
)
|
2407
|
+
cte = CTEFactory(
|
2408
|
+
"Sales(year$ref_date:ref_year@, sum$quantity:qty_sold, vendor) <- Vendor(id, name@)"
|
2409
|
+
# ^^^ ^^^ ^^^
|
2410
|
+
# | | | ^^^ ^^^
|
2411
|
+
# | | | | |
|
2412
|
+
# | | | Relaciona Sales com Vendor ----+ |
|
2413
|
+
# | | | |
|
2414
|
+
# | | +---- Chama de `ref_year` e agrupa |
|
2415
|
+
# | | |
|
2416
|
+
# | +-- Extrai o ano do campo `ref_date` |
|
2417
|
+
# | |
|
2418
|
+
# +--- Tabela de vendas |
|
2419
|
+
# Agrupa também pelo nome do vendedor -------------+
|
2399
2420
|
)
|
2400
|
-
print(cte)
|
2421
|
+
print(cte)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.20250711
|
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=JHQ0CzciUEodZoA0WjUYKDpC2VZWcFlDB9C2wrNc4rA,83004
|
3
|
+
sql_blocks-1.20250711.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-1.20250711.dist-info/METADATA,sha256=fci6o5QrXStVrXylRQ7QaCpO9jid0P6eON6xMK4Rob0,24486
|
5
|
+
sql_blocks-1.20250711.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-1.20250711.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-1.20250711.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
|
2
|
-
sql_blocks/sql_blocks.py,sha256=FLjT_V60QyfqUvbdu2hKUcFh3KTJNP091p0q_pg43v4,81469
|
3
|
-
sql_blocks-1.20250710.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
-
sql_blocks-1.20250710.dist-info/METADATA,sha256=zuWxpPD-1LoJHSD7D4EywcpQaYi5buEjfuypOmwNdOE,24486
|
5
|
-
sql_blocks-1.20250710.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
-
sql_blocks-1.20250710.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
-
sql_blocks-1.20250710.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|