sql-blocks 1.25.37022003__py3-none-any.whl → 1.25.38021329__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 CHANGED
@@ -196,17 +196,35 @@ class Dialect(Enum):
196
196
  POSTGRESQL = 3
197
197
  MYSQL = 4
198
198
 
199
+ SQL_TYPES = 'CHAR INT DATE FLOAT ANY'.split()
200
+ CHAR, INT, DATE, FLOAT, ANY = SQL_TYPES
201
+
199
202
  class Function:
200
203
  dialect = Dialect.ANSI
201
- need_params = True
204
+ inputs = None
205
+ output = None
202
206
  separator = ', '
207
+ auto_convert = True
208
+ append_param = False
203
209
 
204
210
  def __init__(self, *params: list):
211
+ def set_func_types(param):
212
+ if self.auto_convert and isinstance(param, Function):
213
+ func = param
214
+ main_param = self.inputs[0]
215
+ unfriendly = all([
216
+ func.output != main_param,
217
+ func.output != ANY,
218
+ main_param != ANY
219
+ ])
220
+ if unfriendly:
221
+ return Cast(func, main_param)
222
+ return param
205
223
  # --- Replace class methods by instance methods: ------
206
224
  self.add = self.__add
207
225
  self.format = self.__format
208
226
  # -----------------------------------------------------
209
- self.params = list(params)
227
+ self.params = [set_func_types(p) for p in params]
210
228
  self.field_class = Field
211
229
  self.pattern = self.get_pattern()
212
230
  self.extra = {}
@@ -231,12 +249,14 @@ class Function:
231
249
  param for param in self.params if isinstance(param, Function)
232
250
  ]
233
251
  for func in nested_functions:
234
- if func.need_params:
252
+ if func.inputs:
235
253
  func.set_main_param(name, main)
236
254
  return
237
- self.params = [
238
- Field.format(name, main)
239
- ] + self.params
255
+ new_params = [Field.format(name, main)]
256
+ if self.append_param:
257
+ self.params += new_params
258
+ else:
259
+ self.params = new_params + self.params
240
260
 
241
261
  def __format(self, name: str, main: SQLObject) -> str:
242
262
  if name not in '*_':
@@ -260,6 +280,9 @@ class Function:
260
280
 
261
281
  # ---- String Functions: ---------------------------------
262
282
  class SubString(Function):
283
+ inputs = [CHAR, INT, INT]
284
+ output = CHAR
285
+
263
286
  def get_pattern(self) -> str:
264
287
  if self.dialect in (Dialect.ORACLE, Dialect.MYSQL):
265
288
  return 'Substr({params})'
@@ -267,33 +290,54 @@ class SubString(Function):
267
290
 
268
291
  # ---- Numeric Functions: --------------------------------
269
292
  class Round(Function):
270
- ...
293
+ inputs = [FLOAT]
294
+ output = FLOAT
271
295
 
272
296
  # --- Date Functions: ------------------------------------
273
297
  class DateDiff(Function):
274
- def get_pattern(self) -> str:
298
+ inputs = [DATE]
299
+ output = DATE
300
+ append_param = True
301
+
302
+ def __str__(self) -> str:
275
303
  def is_field_or_func(name: str) -> bool:
276
- return re.sub('[()]', '', name).isidentifier()
277
- params = [str(p) for p in self.params]
304
+ candidate = re.sub(
305
+ '[()]', '', name.split('.')[-1]
306
+ )
307
+ return candidate.isidentifier()
278
308
  if self.dialect != Dialect.SQL_SERVER:
309
+ params = [str(p) for p in self.params]
279
310
  return ' - '.join(
280
311
  p if is_field_or_func(p) else f"'{p}'"
281
312
  for p in params
282
313
  ) # <==== Date subtract
283
- return super().get_pattern()
314
+ return super().__str__()
315
+
316
+
317
+ class DatePart(Function):
318
+ inputs = [DATE]
319
+ output = INT
284
320
 
285
- class Year(Function):
286
321
  def get_pattern(self) -> str:
322
+ interval = self.__class__.__name__
287
323
  database_type = {
288
- Dialect.ORACLE: 'Extract(YEAR FROM {params})',
289
- Dialect.POSTGRESQL: "Date_Part('year', {params})",
324
+ Dialect.ORACLE: 'Extract('+interval+' FROM {params})',
325
+ Dialect.POSTGRESQL: "Date_Part('"+interval+"', {params})",
290
326
  }
291
327
  if self.dialect in database_type:
292
328
  return database_type[self.dialect]
293
329
  return super().get_pattern()
294
330
 
331
+ class Year(DatePart):
332
+ ...
333
+ class Month(DatePart):
334
+ ...
335
+ class Day(DatePart):
336
+ ...
337
+
338
+
295
339
  class Current_Date(Function):
296
- need_params = False
340
+ output = DATE
297
341
 
298
342
  def get_pattern(self) -> str:
299
343
  database_type = {
@@ -364,8 +408,12 @@ class Lead(Window, Function):
364
408
 
365
409
  # ---- Conversions and other Functions: ---------------------
366
410
  class Coalesce(Function):
367
- ...
411
+ inputs = [ANY]
412
+ output = ANY
413
+
368
414
  class Cast(Function):
415
+ inputs = [ANY]
416
+ output = ANY
369
417
  separator = ' As '
370
418
 
371
419
 
@@ -1728,4 +1776,4 @@ def detect(text: str, join_queries: bool = True, format: str='') -> Select | lis
1728
1776
  for query in query_list[1:]:
1729
1777
  result += query
1730
1778
  return result
1731
- # ===========================================================================================//
1779
+ # ===========================================================================================//
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql_blocks
3
- Version: 1.25.37022003
3
+ Version: 1.25.38021329
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
@@ -693,6 +693,22 @@ Results...
693
693
  SELECT ...
694
694
  SubString(Cast(event_date As char), 12, 19) as time
695
695
  ```
696
+
697
+ >> `Function.auto_convert` option (default: True)
698
+
699
+ - Put Cast(...) when there is a difference between the types of the parameter and the return of the nested function
700
+ ```
701
+ birth=Round( DateDiff(Current_Date()) ).As('age')
702
+ ```
703
+ ...Returns...
704
+ ```
705
+ SELECT
706
+ Round(
707
+ Cast(Current_Date() - p.birth As FLOAT)
708
+ /* ^^^ */
709
+ ) as age
710
+ ...
711
+ ```
696
712
  ---
697
713
 
698
714
  ### 17 - CTE and Recursive classes
@@ -0,0 +1,7 @@
1
+ sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
+ sql_blocks/sql_blocks.py,sha256=5LQPEOkvMylJJxoU2m1P6pAhfcMHVdsnTiYgfLLJ5bQ,59477
3
+ sql_blocks-1.25.38021329.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
+ sql_blocks-1.25.38021329.dist-info/METADATA,sha256=un6TFbAfNbyhIrjLzHpvG1Yy77jsyZCw2xy_i3tMw2k,20511
5
+ sql_blocks-1.25.38021329.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
+ sql_blocks-1.25.38021329.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
+ sql_blocks-1.25.38021329.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
- sql_blocks/sql_blocks.py,sha256=kaI6nCcq1X3CenGFP4HkKkk3rsDt_jts8xErg-ml7dk,58217
3
- sql_blocks-1.25.37022003.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
- sql_blocks-1.25.37022003.dist-info/METADATA,sha256=AUa01HeqYtgwVObYWMTkqixy0RNoxwNQXurTMEWjjQ8,20146
5
- sql_blocks-1.25.37022003.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- sql_blocks-1.25.37022003.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
- sql_blocks-1.25.37022003.dist-info/RECORD,,