sql-blocks 1.25.13__py3-none-any.whl → 1.25.109__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
@@ -26,7 +26,7 @@ TO_LIST = lambda x: x if isinstance(x, list) else [x]
26
26
 
27
27
 
28
28
  class SQLObject:
29
- ALIAS_FUNC = lambda t: t.lower()[:3]
29
+ ALIAS_FUNC = None
30
30
  """ ^^^^^^^^^^^^^^^^^^^^^^^^
31
31
  You can change the behavior by assigning
32
32
  a user function to SQLObject.ALIAS_FUNC
@@ -41,7 +41,10 @@ class SQLObject:
41
41
  def set_table(self, table_name: str):
42
42
  if not table_name:
43
43
  return
44
- if ' ' in table_name.strip():
44
+ cls = SQLObject
45
+ if cls.ALIAS_FUNC:
46
+ self.__alias = cls.ALIAS_FUNC(table_name)
47
+ elif ' ' in table_name.strip():
45
48
  table_name, self.__alias = table_name.split()
46
49
  elif '_' in table_name:
47
50
  self.__alias = ''.join(
@@ -49,7 +52,7 @@ class SQLObject:
49
52
  for word in table_name.split('_')
50
53
  )
51
54
  else:
52
- self.__alias = SQLObject.ALIAS_FUNC(table_name)
55
+ self.__alias = table_name.lower()[:3]
53
56
  self.values.setdefault(FROM, []).append(f'{table_name} {self.alias}')
54
57
 
55
58
  @property
@@ -111,15 +114,26 @@ class SQLObject:
111
114
  self.values[key] = result
112
115
 
113
116
 
117
+ SQL_CONST_SYSDATE = 'SYSDATE'
118
+ SQL_CONST_CURR_DATE = 'Current_date'
119
+ SQL_CONSTS = [SQL_CONST_SYSDATE, SQL_CONST_CURR_DATE]
120
+
121
+
114
122
  class Field:
115
123
  prefix = ''
116
124
 
117
125
  @classmethod
118
126
  def format(cls, name: str, main: SQLObject) -> str:
127
+ def is_const() -> bool:
128
+ return any([
129
+ re.findall('[.()0-9]', name),
130
+ name in SQL_CONSTS,
131
+ re.findall(r'\w+\s*[+-]\s*\w+', name)
132
+ ])
119
133
  name = name.strip()
120
134
  if name in ('_', '*'):
121
135
  name = '*'
122
- elif not re.findall('[.()0-9]', name):
136
+ elif not is_const():
123
137
  name = f'{main.alias}.{name}'
124
138
  if Function in cls.__bases__:
125
139
  name = f'{cls.__name__}({name})'
@@ -150,7 +164,16 @@ class NamedField:
150
164
  )
151
165
 
152
166
 
167
+ class Dialect(Enum):
168
+ ANSI = 0
169
+ SQL_SERVER = 1
170
+ ORACLE = 2
171
+ POSTGRESQL = 3
172
+ MYSQL = 4
173
+
153
174
  class Function:
175
+ dialect = Dialect.ANSI
176
+
154
177
  def __init__(self, *params: list):
155
178
  # --- Replace class methods by instance methods: ------
156
179
  self.add = self.__add
@@ -158,26 +181,30 @@ class Function:
158
181
  # -----------------------------------------------------
159
182
  self.params = [str(p) for p in params]
160
183
  self.field_class = Field
161
- self.pattern = '{}({})'
184
+ self.pattern = self.get_pattern()
162
185
  self.extra = {}
163
186
 
187
+ def get_pattern(self) -> str:
188
+ return '{func_name}({params})'
189
+
164
190
  def As(self, field_alias: str, modifiers=None):
165
191
  if modifiers:
166
192
  self.extra[field_alias] = TO_LIST(modifiers)
167
193
  self.field_class = NamedField(field_alias)
168
194
  return self
169
195
 
196
+ def __str__(self) -> str:
197
+ return self.pattern.format(
198
+ func_name=self.__class__.__name__,
199
+ params=', '.join(self.params)
200
+ )
201
+
170
202
  def __format(self, name: str, main: SQLObject) -> str:
171
- if name in '*_' and self.params:
172
- params = self.params
173
- else:
174
- params = [
203
+ if name not in '*_':
204
+ self.params = [
175
205
  Field.format(name, main)
176
206
  ] + self.params
177
- return self.pattern.format(
178
- self.__class__.__name__,
179
- ', '.join(params)
180
- )
207
+ return str(self)
181
208
 
182
209
  @classmethod
183
210
  def format(cls, name: str, main: SQLObject):
@@ -196,7 +223,10 @@ class Function:
196
223
 
197
224
  # ---- String Functions: ---------------------------------
198
225
  class SubString(Function):
199
- ...
226
+ def get_pattern(self) -> str:
227
+ if self.dialect in (Dialect.ORACLE, Dialect.MYSQL):
228
+ return 'Substr({params})'
229
+ return super().get_pattern()
200
230
 
201
231
  # ---- Numeric Functions: --------------------------------
202
232
  class Round(Function):
@@ -204,13 +234,37 @@ class Round(Function):
204
234
 
205
235
  # --- Date Functions: ------------------------------------
206
236
  class DateDiff(Function):
207
- ...
208
- class Extract(Function):
209
- ...
210
- class DatePart(Function):
211
- ...
237
+ def get_pattern(self) -> str:
238
+ def is_field_or_func(name: str) -> bool:
239
+ return re.sub('[()]', '', name).isidentifier()
240
+ if self.dialect != Dialect.SQL_SERVER:
241
+ return ' - '.join(
242
+ p if is_field_or_func(p) else f"'{p}'"
243
+ for p in self.params
244
+ ) # <==== Date subtract
245
+ return super().get_pattern()
246
+
247
+ class Year(Function):
248
+ def get_pattern(self) -> str:
249
+ database_type = {
250
+ Dialect.ORACLE: 'Extract(YEAR FROM {params})',
251
+ Dialect.POSTGRESQL: "Date_Part('year', {params})",
252
+ }
253
+ if self.dialect in database_type:
254
+ return database_type[self.dialect]
255
+ return super().get_pattern()
256
+
212
257
  class Current_Date(Function):
213
- ...
258
+ def get_pattern(self) -> str:
259
+ database_type = {
260
+ Dialect.ORACLE: SQL_CONST_SYSDATE,
261
+ Dialect.POSTGRESQL: SQL_CONST_CURR_DATE,
262
+ Dialect.SQL_SERVER: 'getDate()'
263
+ }
264
+ if self.dialect in database_type:
265
+ return database_type[self.dialect]
266
+ return super().get_pattern()
267
+ # --------------------------------------------------------
214
268
 
215
269
  class Aggregate:
216
270
  break_lines: bool = True
@@ -225,7 +279,7 @@ class Aggregate:
225
279
  )
226
280
  if keywords and self.break_lines:
227
281
  keywords += '\n\t'
228
- self.pattern = '{}({})' + f' OVER({keywords})'
282
+ self.pattern = self.get_pattern() + f' OVER({keywords})'
229
283
  return self
230
284
 
231
285
 
@@ -324,6 +378,13 @@ def quoted(value) -> str:
324
378
  return str(value)
325
379
 
326
380
 
381
+ class Position(Enum):
382
+ Middle = "LIKE '%{}%'"
383
+ StartWith = "LIKE '{}%'"
384
+ EndsWith = "LIKE '%{}'"
385
+ RegEx = "REGEXP_LIKE('{}')"
386
+
387
+
327
388
  class Where:
328
389
  prefix = ''
329
390
 
@@ -339,8 +400,8 @@ class Where:
339
400
  return cls.__constructor('=', value)
340
401
 
341
402
  @classmethod
342
- def contains(cls, value: str):
343
- return cls(f"LIKE '%{value}%'")
403
+ def contains(cls, content: str, pos: Position = Position.Middle):
404
+ return cls(pos.value.format(content))
344
405
 
345
406
  @classmethod
346
407
  def gt(cls, value):
@@ -1354,12 +1415,3 @@ def detect(text: str) -> Select:
1354
1415
  for query in query_list[1:]:
1355
1416
  result += query
1356
1417
  return result
1357
-
1358
- if __name__ == "__main__":
1359
- OrderBy.sort = SortType.DESC
1360
- query = Select(
1361
- 'order_Detail d',
1362
- customer_id=GroupBy,
1363
- _=Sum('d.unitPrice * d.quantity').As('total', OrderBy)
1364
- )
1365
- print(query)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql_blocks
3
- Version: 1.25.13
3
+ Version: 1.25.109
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=OnIlTb03DTgK_U8QBnXQtQ-rKrkSuKNj1hjJiHogmYE,47639
3
+ sql_blocks-1.25.109.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
+ sql_blocks-1.25.109.dist-info/METADATA,sha256=TRybMQgmXhlz14FxEV6f4rg0-gTPpveyQi3xEYPdZ1w,13425
5
+ sql_blocks-1.25.109.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
+ sql_blocks-1.25.109.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
+ sql_blocks-1.25.109.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
- sql_blocks/sql_blocks.py,sha256=P5yp0Ug4PD56xklmQOtpNLKm9hfhHBNb8TDkOneNAHw,45783
3
- sql_blocks-1.25.13.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
- sql_blocks-1.25.13.dist-info/METADATA,sha256=tahTyaVcsa4ROoxQSMK41W6m20bVlDs6_kh9b9mkgoc,13424
5
- sql_blocks-1.25.13.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- sql_blocks-1.25.13.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
- sql_blocks-1.25.13.dist-info/RECORD,,