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 +84 -32
- {sql_blocks-1.25.13.dist-info → sql_blocks-1.25.109.dist-info}/METADATA +1 -1
- sql_blocks-1.25.109.dist-info/RECORD +7 -0
- sql_blocks-1.25.13.dist-info/RECORD +0 -7
- {sql_blocks-1.25.13.dist-info → sql_blocks-1.25.109.dist-info}/LICENSE +0 -0
- {sql_blocks-1.25.13.dist-info → sql_blocks-1.25.109.dist-info}/WHEEL +0 -0
- {sql_blocks-1.25.13.dist-info → sql_blocks-1.25.109.dist-info}/top_level.txt +0 -0
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 =
|
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
|
-
|
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 =
|
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
|
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 '*_'
|
172
|
-
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
|
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
|
-
|
209
|
-
|
210
|
-
|
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 =
|
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,
|
343
|
-
return cls(
|
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.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|