sql-blocks 1.2025.628__tar.gz → 1.2025.630__tar.gz
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-1.2025.628/sql_blocks.egg-info → sql_blocks-1.2025.630}/PKG-INFO +24 -2
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/README.md +23 -1
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/pyproject.toml +1 -1
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/setup.py +1 -1
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/sql_blocks/sql_blocks.py +57 -40
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630/sql_blocks.egg-info}/PKG-INFO +24 -2
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/LICENSE +0 -0
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/setup.cfg +0 -0
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/sql_blocks/__init__.py +0 -0
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/sql_blocks.egg-info/SOURCES.txt +0 -0
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/sql_blocks.egg-info/dependency_links.txt +0 -0
- {sql_blocks-1.2025.628 → sql_blocks-1.2025.630}/sql_blocks.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 1.2025.
|
3
|
+
Version: 1.2025.630
|
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
|
@@ -415,7 +415,7 @@ m2 = Select(
|
|
415
415
|
)
|
416
416
|
)
|
417
417
|
|
418
|
-
10.1 - If the labels used in the CASE are based on ranges of values in sequence, you can use the **Range class**:
|
418
|
+
* 10.1 - If the labels used in the CASE are based on ranges of values in sequence, you can use the **Range class**:
|
419
419
|
|
420
420
|
query = Select(
|
421
421
|
'People p',
|
@@ -440,6 +440,28 @@ is equivalent to...
|
|
440
440
|
FROM
|
441
441
|
People p
|
442
442
|
```
|
443
|
+
|
444
|
+
* 10.2 `If` class
|
445
|
+
|
446
|
+
Usefull to conditional Sum, Avg, Count...
|
447
|
+
|
448
|
+
**Example:**
|
449
|
+
|
450
|
+
Select('Emprestimo',
|
451
|
+
taxa=If('atraso', gt(0), Sum)
|
452
|
+
)
|
453
|
+
|
454
|
+
results...
|
455
|
+
```
|
456
|
+
SELECT
|
457
|
+
Sum(CASE
|
458
|
+
WHEN atraso > 0 THEN taxa
|
459
|
+
ELSE 0
|
460
|
+
END)
|
461
|
+
FROM
|
462
|
+
Emprestimo
|
463
|
+
```
|
464
|
+
|
443
465
|
---
|
444
466
|
|
445
467
|
### 11 - optimize method
|
@@ -400,7 +400,7 @@ m2 = Select(
|
|
400
400
|
)
|
401
401
|
)
|
402
402
|
|
403
|
-
10.1 - If the labels used in the CASE are based on ranges of values in sequence, you can use the **Range class**:
|
403
|
+
* 10.1 - If the labels used in the CASE are based on ranges of values in sequence, you can use the **Range class**:
|
404
404
|
|
405
405
|
query = Select(
|
406
406
|
'People p',
|
@@ -425,6 +425,28 @@ is equivalent to...
|
|
425
425
|
FROM
|
426
426
|
People p
|
427
427
|
```
|
428
|
+
|
429
|
+
* 10.2 `If` class
|
430
|
+
|
431
|
+
Usefull to conditional Sum, Avg, Count...
|
432
|
+
|
433
|
+
**Example:**
|
434
|
+
|
435
|
+
Select('Emprestimo',
|
436
|
+
taxa=If('atraso', gt(0), Sum)
|
437
|
+
)
|
438
|
+
|
439
|
+
results...
|
440
|
+
```
|
441
|
+
SELECT
|
442
|
+
Sum(CASE
|
443
|
+
WHEN atraso > 0 THEN taxa
|
444
|
+
ELSE 0
|
445
|
+
END)
|
446
|
+
FROM
|
447
|
+
Emprestimo
|
448
|
+
```
|
449
|
+
|
428
450
|
---
|
429
451
|
|
430
452
|
### 11 - optimize method
|
@@ -210,6 +210,34 @@ class NamedField:
|
|
210
210
|
)
|
211
211
|
|
212
212
|
|
213
|
+
class Code:
|
214
|
+
def __init__(self):
|
215
|
+
# --- Replace class method by instance method: ------
|
216
|
+
self.add = self.__add
|
217
|
+
# -----------------------------------------------------
|
218
|
+
self.field_class = Field
|
219
|
+
self.extra = {}
|
220
|
+
|
221
|
+
def As(self, field_alias: str, modifiers=None):
|
222
|
+
if modifiers:
|
223
|
+
self.extra[field_alias] = TO_LIST(modifiers)
|
224
|
+
self.field_class = NamedField(field_alias)
|
225
|
+
return self
|
226
|
+
|
227
|
+
def format(self, name: str, main: SQLObject) -> str:
|
228
|
+
raise NotImplementedError('Use child classes instead of this one')
|
229
|
+
|
230
|
+
def __add(self, name: str, main: SQLObject):
|
231
|
+
name = self.format(name, main)
|
232
|
+
self.field_class.add(name, main)
|
233
|
+
if self.extra:
|
234
|
+
main.__call__(**self.extra)
|
235
|
+
|
236
|
+
@classmethod
|
237
|
+
def add(cls, name: str, main: SQLObject):
|
238
|
+
cls().__add(name, main)
|
239
|
+
|
240
|
+
|
213
241
|
class Dialect(Enum):
|
214
242
|
ANSI = 0
|
215
243
|
SQL_SERVER = 1
|
@@ -220,7 +248,7 @@ class Dialect(Enum):
|
|
220
248
|
SQL_TYPES = 'CHAR INT DATE FLOAT ANY'.split()
|
221
249
|
CHAR, INT, DATE, FLOAT, ANY = SQL_TYPES
|
222
250
|
|
223
|
-
class Function:
|
251
|
+
class Function(Code):
|
224
252
|
dialect = Dialect.ANSI
|
225
253
|
inputs = None
|
226
254
|
output = None
|
@@ -241,24 +269,13 @@ class Function:
|
|
241
269
|
if unfriendly:
|
242
270
|
return Cast(func, main_param)
|
243
271
|
return param
|
244
|
-
# --- Replace class methods by instance methods: ------
|
245
|
-
self.add = self.__add
|
246
|
-
self.format = self.__format
|
247
|
-
# -----------------------------------------------------
|
248
272
|
self.params = [set_func_types(p) for p in params]
|
249
|
-
self.field_class = Field
|
250
273
|
self.pattern = self.get_pattern()
|
251
|
-
|
274
|
+
super().__init__()
|
252
275
|
|
253
276
|
def get_pattern(self) -> str:
|
254
277
|
return '{func_name}({params})'
|
255
278
|
|
256
|
-
def As(self, field_alias: str, modifiers=None):
|
257
|
-
if modifiers:
|
258
|
-
self.extra[field_alias] = TO_LIST(modifiers)
|
259
|
-
self.field_class = NamedField(field_alias)
|
260
|
-
return self
|
261
|
-
|
262
279
|
def __str__(self) -> str:
|
263
280
|
return self.pattern.format(
|
264
281
|
func_name=self.__class__.__name__,
|
@@ -288,24 +305,11 @@ class Function:
|
|
288
305
|
else:
|
289
306
|
self.params = new_params + self.params
|
290
307
|
|
291
|
-
def
|
308
|
+
def format(self, name: str, main: SQLObject) -> str:
|
292
309
|
if name not in '*_':
|
293
310
|
self.set_main_param(name, main)
|
294
311
|
return str(self)
|
295
312
|
|
296
|
-
@classmethod
|
297
|
-
def format(cls, name: str, main: SQLObject):
|
298
|
-
return cls().__format(name, main)
|
299
|
-
|
300
|
-
def __add(self, name: str, main: SQLObject):
|
301
|
-
name = self.format(name, main)
|
302
|
-
self.field_class.add(name, main)
|
303
|
-
if self.extra:
|
304
|
-
main.__call__(**self.extra)
|
305
|
-
|
306
|
-
@classmethod
|
307
|
-
def add(cls, name: str, main: SQLObject):
|
308
|
-
cls().__add(name, main)
|
309
313
|
|
310
314
|
|
311
315
|
# ---- String Functions: ---------------------------------
|
@@ -336,7 +340,6 @@ class DateDiff(Function):
|
|
336
340
|
candidate = re.sub(
|
337
341
|
'[()]', '', obj.split('.')[-1]
|
338
342
|
)
|
339
|
-
print(f'---------------> #{candidate=}#')
|
340
343
|
return candidate.isidentifier()
|
341
344
|
self.params = [
|
342
345
|
p if is_field_or_func(p) else f"'{p}'"
|
@@ -676,7 +679,10 @@ class Case:
|
|
676
679
|
|
677
680
|
def then(self, result):
|
678
681
|
if isinstance(result, str):
|
679
|
-
result
|
682
|
+
if result.startswith('='):
|
683
|
+
result = result[1:]
|
684
|
+
else:
|
685
|
+
result = quoted(result)
|
680
686
|
self.__conditions[result] = self.current_condition
|
681
687
|
return self
|
682
688
|
|
@@ -748,7 +754,10 @@ class Case:
|
|
748
754
|
while tokens:
|
749
755
|
word = tokens.pop(0)
|
750
756
|
if last_word in KEYWORDS:
|
751
|
-
|
757
|
+
try:
|
758
|
+
block = KEYWORDS[last_word](word)
|
759
|
+
except:
|
760
|
+
break
|
752
761
|
result += block.fields
|
753
762
|
block.fields = []
|
754
763
|
elif word not in RESERVED_WORDS:
|
@@ -757,6 +766,23 @@ class Case:
|
|
757
766
|
return result
|
758
767
|
|
759
768
|
|
769
|
+
class If(Code, Frame):
|
770
|
+
"""
|
771
|
+
Behaves like an aggregation function
|
772
|
+
"""
|
773
|
+
def __init__(self, field: str, condition: Where, func_class: Function):
|
774
|
+
self.field = field
|
775
|
+
self.condition = condition
|
776
|
+
self.func_class = func_class
|
777
|
+
super().__init__()
|
778
|
+
|
779
|
+
def format(self, name: str, main: SQLObject) -> str:
|
780
|
+
return '{func}({param})'.format(
|
781
|
+
func=self.func_class.__name__,
|
782
|
+
param=Case(self.field).when(self.condition, f'={name}').else_value(0)
|
783
|
+
)
|
784
|
+
|
785
|
+
|
760
786
|
class Options:
|
761
787
|
def __init__(self, **values):
|
762
788
|
self.__children: dict = values
|
@@ -916,7 +942,7 @@ class Having:
|
|
916
942
|
|
917
943
|
def add(self, name: str, main:SQLObject):
|
918
944
|
main.values[GROUP_BY][-1] += ' HAVING {} {}'.format(
|
919
|
-
self.function.format(name, main), self.condition.content
|
945
|
+
self.function().format(name, main), self.condition.content
|
920
946
|
)
|
921
947
|
|
922
948
|
@classmethod
|
@@ -2296,12 +2322,3 @@ def detect(text: str, join_queries: bool = True, format: str='') -> Select | lis
|
|
2296
2322
|
result += query
|
2297
2323
|
return result
|
2298
2324
|
# ===========================================================================================//
|
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.630
|
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
|
@@ -415,7 +415,7 @@ m2 = Select(
|
|
415
415
|
)
|
416
416
|
)
|
417
417
|
|
418
|
-
10.1 - If the labels used in the CASE are based on ranges of values in sequence, you can use the **Range class**:
|
418
|
+
* 10.1 - If the labels used in the CASE are based on ranges of values in sequence, you can use the **Range class**:
|
419
419
|
|
420
420
|
query = Select(
|
421
421
|
'People p',
|
@@ -440,6 +440,28 @@ is equivalent to...
|
|
440
440
|
FROM
|
441
441
|
People p
|
442
442
|
```
|
443
|
+
|
444
|
+
* 10.2 `If` class
|
445
|
+
|
446
|
+
Usefull to conditional Sum, Avg, Count...
|
447
|
+
|
448
|
+
**Example:**
|
449
|
+
|
450
|
+
Select('Emprestimo',
|
451
|
+
taxa=If('atraso', gt(0), Sum)
|
452
|
+
)
|
453
|
+
|
454
|
+
results...
|
455
|
+
```
|
456
|
+
SELECT
|
457
|
+
Sum(CASE
|
458
|
+
WHEN atraso > 0 THEN taxa
|
459
|
+
ELSE 0
|
460
|
+
END)
|
461
|
+
FROM
|
462
|
+
Emprestimo
|
463
|
+
```
|
464
|
+
|
443
465
|
---
|
444
466
|
|
445
467
|
### 11 - optimize method
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|