sql-blocks 0.0.1__tar.gz → 0.0.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql_blocks
3
- Version: 0.0.1
3
+ Version: 0.0.2
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
@@ -35,7 +35,7 @@ You can specify your own alias: `a = Select('Actor a')`
35
35
 
36
36
  - Select(
37
37
  'Actor a',
38
- name=NamedField('actors_name'), Distinct
38
+ name=NamedField('actors_name', Distinct)
39
39
  )
40
40
 
41
41
  ---
@@ -20,7 +20,7 @@ You can specify your own alias: `a = Select('Actor a')`
20
20
 
21
21
  - Select(
22
22
  'Actor a',
23
- name=NamedField('actors_name'), Distinct
23
+ name=NamedField('actors_name', Distinct)
24
24
  )
25
25
 
26
26
  ---
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sql_blocks"
3
- version = "0.0.1"
3
+ version = "0.0.2"
4
4
  authors = [
5
5
  { name="Julio Cascalles", email="julio.cascalles@outlook.com" },
6
6
  ]
@@ -3,7 +3,7 @@ from setuptools import setup
3
3
 
4
4
  setup(
5
5
  name = 'sql_blocks',
6
- version = '1.0.0',
6
+ version = '0.0.2',
7
7
  author = 'Júlio Cascalles',
8
8
  author_email = 'julio.cascalles@outlook.com',
9
9
  packages = ['sql_blocks'],
@@ -11,6 +11,7 @@ KEYWORD = {
11
11
  SELECT, FROM, WHERE, GROUP_BY, ORDER_BY, LIMIT = KEYWORD.keys()
12
12
  USUAL_KEYS = [SELECT, WHERE, GROUP_BY, ORDER_BY]
13
13
 
14
+
14
15
  class SQLObject:
15
16
  def __init__(self, table_name: str=''):
16
17
  self.alias = ''
@@ -133,15 +134,21 @@ class ForeignKey:
133
134
  return cls.references.get(key, '').split('_')
134
135
 
135
136
 
137
+ def quoted(value) -> str:
138
+ if isinstance(value, str):
139
+ value = f"'{value}'"
140
+ return str(value)
141
+
142
+
136
143
  class Where:
144
+ prefix = ''
145
+
137
146
  def __init__(self, expr: str):
138
- self.expr = expr
147
+ self.expr = f'{self.prefix}{expr}'
139
148
 
140
149
  @classmethod
141
150
  def __constructor(cls, operator: str, value):
142
- if isinstance(value, str):
143
- return cls(expr=f"{operator} '{value}'")
144
- return cls(expr=f'{operator} {value}')
151
+ return cls(expr=f'{operator} {quoted(value)}')
145
152
 
146
153
  @classmethod
147
154
  def eq(cls, value):
@@ -164,8 +171,18 @@ class Where:
164
171
  return cls.__constructor('<', value)
165
172
 
166
173
  @classmethod
167
- def lte(cls, value) -> str:
174
+ def lte(cls, value):
168
175
  return cls.__constructor('<=', value)
176
+
177
+ @classmethod
178
+ def is_null(cls):
179
+ return cls('IS NULL')
180
+
181
+ @classmethod
182
+ def list(cls, values):
183
+ if isinstance(values, list):
184
+ values = ','.join(quoted(v) for v in values)
185
+ return cls(f'IN ({values})')
169
186
 
170
187
  def add(self, name: str, main: SQLObject):
171
188
  main.values.setdefault(WHERE, []).append('{} {}'.format(
@@ -173,6 +190,41 @@ class Where:
173
190
  ))
174
191
 
175
192
 
193
+ class Not(Where):
194
+ prefix = 'NOT '
195
+
196
+ @classmethod
197
+ def eq(cls, value):
198
+ return Where.__constructor('<>', value)
199
+
200
+
201
+ class Case:
202
+ def __init__(self, field: str):
203
+ self.__conditions = {}
204
+ self.default = None
205
+ self.field = field
206
+
207
+ def when(self, condition: Where, result: str):
208
+ self.__conditions[result] = condition
209
+ return self
210
+
211
+ def else_value(self, default: str):
212
+ self.default = default
213
+ return self
214
+
215
+ def add(self, name: str, main: SQLObject):
216
+ field = Field.format(self.field, main)
217
+ default = quoted(self.default)
218
+ name = 'CASE \n{}\n\tEND AS {}'.format(
219
+ '\n'.join(
220
+ f'\t\tWHEN {field} {cond.expr} THEN {quoted(res)}'
221
+ for res, cond in self.__conditions.items()
222
+ ) + f'\n\t\tELSE {default}' if default else '',
223
+ name
224
+ )
225
+ main.values.setdefault(SELECT, []).append(name)
226
+
227
+
176
228
  class Options:
177
229
  def __init__(self, **values):
178
230
  self.__children: dict = values
@@ -266,10 +318,7 @@ class Select(SQLObject):
266
318
 
267
319
  def __init__(self, table_name: str='', **values):
268
320
  super().__init__(table_name)
269
- to_list = lambda x: x if isinstance(x, list) else [x]
270
- for name, params in values.items():
271
- for obj in to_list(params):
272
- obj.add(name, self)
321
+ self.__call__(**values)
273
322
  self.break_lines = True
274
323
 
275
324
  def add(self, name: str, main: SQLObject):
@@ -319,10 +368,12 @@ class Select(SQLObject):
319
368
  return f'{select}{_from}{where}{groupBy}{orderBy}{limit}'.strip()
320
369
 
321
370
  def __call__(self, **values):
322
- for name, obj in values.items():
323
- obj.add(name, self)
371
+ to_list = lambda x: x if isinstance(x, list) else [x]
372
+ for name, params in values.items():
373
+ for obj in to_list(params):
374
+ obj.add(name, self)
324
375
  return self
325
-
376
+
326
377
  def __eq__(self, other: SQLObject) -> bool:
327
378
  def sorted_values(obj: SQLObject, key: str) -> list:
328
379
  return sorted(obj.values.get(key, []))
@@ -380,4 +431,4 @@ class Select(SQLObject):
380
431
  class SubSelect(Select):
381
432
  def add(self, name: str, main: SQLObject):
382
433
  self.break_lines = False
383
- Where(f'IN ({self})').add(name, main)
434
+ Where.list(self).add(name, main)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql_blocks
3
- Version: 0.0.1
3
+ Version: 0.0.2
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
@@ -35,7 +35,7 @@ You can specify your own alias: `a = Select('Actor a')`
35
35
 
36
36
  - Select(
37
37
  'Actor a',
38
- name=NamedField('actors_name'), Distinct
38
+ name=NamedField('actors_name', Distinct)
39
39
  )
40
40
 
41
41
  ---
@@ -1,6 +1,9 @@
1
- from sql_blocks import *
1
+ from sql_blocks.sql_blocks import *
2
2
 
3
3
 
4
+ Select.join_type = JoinType.LEFT
5
+ OrderBy.sort = SortType.DESC
6
+
4
7
  def best_movies() -> SubSelect:
5
8
  return SubSelect(
6
9
  'Review r', movie=[GroupBy, Distinct], rate=Having.avg(Where.gt(4.5))
@@ -24,7 +27,7 @@ def detached_objects() -> tuple:
24
27
  )
25
28
  return select_actor(), select_cast(), select_movie()
26
29
 
27
- def expected_result() -> Select:
30
+ def query_reference() -> Select:
28
31
  return Select('Actor a', age=Between(45, 69),
29
32
  cast=Select(
30
33
  Cast=Table('role'), id=PrimaryKey,
@@ -78,13 +81,3 @@ def many_texts_to_objects():
78
81
  WHERE ( m.genre = 'Sci-Fi' OR m.awards LIKE '%Oscar%' ) GROUP BY director
79
82
  """)[0]
80
83
  return actor, cast, movie
81
-
82
- Select.join_type = JoinType.LEFT
83
- OrderBy.sort = SortType.DESC
84
- b = best_movies()
85
- for func in [single_text_to_objects, detached_objects, many_texts_to_objects]:
86
- a, c, m = func()
87
- m.delete('director')
88
- m = m(id=b)
89
- query = a + (m + c)
90
- assert query == expected_result()
File without changes
File without changes