sql-blocks 0.1.4__py3-none-any.whl → 0.2.0__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
@@ -176,17 +176,27 @@ class ExpressionField:
176
176
  a=main.alias, f=name, t=main.table_name
177
177
  )
178
178
 
179
+ class FieldList:
180
+ separator = ','
179
181
 
180
- class Table:
181
- def __init__(self, fields: list=[]):
182
+ def __init__(self, fields: list=[], class_types = [Field]):
182
183
  if isinstance(fields, str):
183
- fields = [f.strip() for f in fields.split(',')]
184
+ fields = [
185
+ f.strip() for f in fields.split(self.separator)
186
+ ]
184
187
  self.fields = fields
188
+ self.class_types = class_types
185
189
 
186
190
  def add(self, name: str, main: SQLObject):
187
- main.set_table(name)
188
191
  for field in self.fields:
189
- Field.add(field, main)
192
+ for class_type in self.class_types:
193
+ class_type.add(field, main)
194
+
195
+
196
+ class Table(FieldList):
197
+ def add(self, name: str, main: SQLObject):
198
+ main.set_table(name)
199
+ super().add(name, main)
190
200
 
191
201
 
192
202
  class PrimaryKey:
@@ -261,7 +271,7 @@ class Where:
261
271
  return cls('IS NULL')
262
272
 
263
273
  @classmethod
264
- def list(cls, values):
274
+ def contains(cls, values):
265
275
  if isinstance(values, list):
266
276
  values = ','.join(quoted(v) for v in values)
267
277
  return cls(f'IN ({values})')
@@ -272,6 +282,12 @@ class Where:
272
282
  ))
273
283
 
274
284
 
285
+ eq, like, gt, gte, lt, lte, is_null, contains = (
286
+ getattr(Where, method) for method in
287
+ ('eq', 'like', 'gt', 'gte', 'lt', 'lte', 'is_null', 'contains')
288
+ )
289
+
290
+
275
291
  class Not(Where):
276
292
  prefix = 'NOT '
277
293
 
@@ -346,9 +362,12 @@ class OrderBy:
346
362
  sort: SortType = SortType.ASC
347
363
  @classmethod
348
364
  def add(cls, name: str, main: SQLObject):
349
- if main.alias:
365
+ found = re.findall(r'^_\d', name)
366
+ if found:
367
+ name = found[0].replace('_', '')
368
+ elif main.alias:
350
369
  name = f'{main.alias}.{name}'
351
- main.values.setdefault(ORDER_BY, []).append(name + cls.sort.value)
370
+ main.values.setdefault(ORDER_BY, []).append(name+cls.sort.value)
352
371
 
353
372
 
354
373
  class GroupBy:
@@ -414,17 +433,16 @@ class Select(SQLObject):
414
433
  self.values.setdefault(key, []).append(value)
415
434
 
416
435
  def add(self, name: str, main: SQLObject):
417
- new_tables = [
436
+ old_tables = main.values.get(FROM, [])
437
+ new_tables = set([
418
438
  '{jt}JOIN {tb} {a2} ON ({a1}.{f1} = {a2}.{f2})'.format(
419
439
  jt=self.join_type.value,
420
440
  tb=self.table_name,
421
441
  a1=main.alias, f1=name,
422
442
  a2=self.alias, f2=self.key_field
423
443
  )
424
- ]
425
- if new_tables not in main.values.get(FROM, []):
426
- new_tables += self.values[FROM][1:]
427
- main.values.setdefault(FROM, []).extend(new_tables)
444
+ ] + old_tables[1:])
445
+ main.values[FROM] = old_tables[:1] + list(new_tables)
428
446
  for key in USUAL_KEYS:
429
447
  main.update_values(key, self.values.get(key, []))
430
448
 
@@ -557,13 +575,22 @@ class Select(SQLObject):
557
575
  for rule in rules:
558
576
  rule.apply(self)
559
577
 
578
+ def add_fields(self, fields: list, order_by: bool=False, group_by:bool=False):
579
+ class_types = [Field]
580
+ if order_by:
581
+ class_types += [OrderBy]
582
+ if group_by:
583
+ class_types += [GroupBy]
584
+ FieldList(fields, class_types).add('', self)
585
+
586
+
560
587
 
561
588
  class SelectIN(Select):
562
589
  condition_class = Where
563
590
 
564
591
  def add(self, name: str, main: SQLObject):
565
592
  self.break_lines = False
566
- self.condition_class.list(self).add(name, main)
593
+ self.condition_class.contains(self).add(name, main)
567
594
 
568
595
  SubSelect = SelectIN
569
596
 
@@ -578,6 +605,7 @@ class RulePutLimit(Rule):
578
605
  if need_limit:
579
606
  target.limit()
580
607
 
608
+
581
609
  class RuleSelectIN(Rule):
582
610
  @classmethod
583
611
  def apply(cls, target: Select):
@@ -592,6 +620,7 @@ class RuleSelectIN(Rule):
592
620
  ','.join(t.split('=')[-1].strip() for t in tokens)
593
621
  )
594
622
 
623
+
595
624
  class RuleAutoField(Rule):
596
625
  @classmethod
597
626
  def apply(cls, target: Select):
@@ -603,13 +632,11 @@ class RuleAutoField(Rule):
603
632
  s2 = set(target.values[ORDER_BY])
604
633
  target.values.setdefault(SELECT, []).extend( list(s2-s1) )
605
634
 
635
+
606
636
  class RuleLogicalOp(Rule):
607
- REVERSE = {
608
- ">=": "<",
609
- "<=": ">",
610
- "<>": "=",
611
- "=": "<>"
612
- }
637
+ REVERSE = {">=": "<", "<=": ">", "=": "<>"}
638
+ REVERSE |= {v: k for k, v in REVERSE.items()}
639
+
613
640
  @classmethod
614
641
  def apply(cls, target: Select):
615
642
  REGEX = re.compile('({})'.format(
@@ -617,13 +644,14 @@ class RuleLogicalOp(Rule):
617
644
  ))
618
645
  for i, condition in enumerate(target.values.get(WHERE, [])):
619
646
  expr = re.sub('\n|\t', ' ', condition)
620
- tokens = [t for t in re.split(r'(NOT\b|not\b)',expr) if t.strip()]
621
- if len(tokens) < 2 or not REGEX.findall(tokens[-1]):
647
+ if not re.search(r'\b(NOT|not)\b', expr):
622
648
  continue
623
- tokens = REGEX.split(tokens[-1])
624
- tokens[1] = cls.REVERSE[tokens[1]]
649
+ tokens = [t.strip() for t in re.split(r'NOT\b|not\b|(<|>|=)', expr) if t]
650
+ op = ''.join(tokens[1: len(tokens)-1])
651
+ tokens = [tokens[0], cls.REVERSE[op], tokens[-1]]
625
652
  target.values[WHERE][i] = ' '.join(tokens)
626
653
 
654
+
627
655
  class RuleDateFuncReplace(Rule):
628
656
  """
629
657
  SQL algorithm by Ralff Matias
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql_blocks
3
- Version: 0.1.4
3
+ Version: 0.2.0
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
@@ -55,12 +55,12 @@ You can specify your own alias: `a = Select('Actor a')`
55
55
  ---
56
56
 
57
57
  ### 3 - To set conditions, use **Where**:
58
- * For example, `a = Select(... age=Where.gt(45) )`
58
+ * For example, `a = Select(... age=gt(45) )`
59
59
 
60
60
  Some possible conditions:
61
- * field=Where.eq(value) - ...the field is EQUAL to the value;
62
- * field=Where.gt(value) - ...the field is GREATER than the value;
63
- * field=Where.lt(value) - ...the field is LESS than the value;
61
+ * field=eq(value) - ...the field is EQUAL to the value;
62
+ * field=gt(value) - ...the field is GREATER than the value;
63
+ * field=lt(value) - ...the field is LESS than the value;
64
64
 
65
65
  3.1 -- If you want to filter the field on a range of values:
66
66
 
@@ -71,7 +71,7 @@ You can specify your own alias: `a = Select('Actor a')`
71
71
  query = Select('Movie m', title=Field,
72
72
  id=SelectIN(
73
73
  'Review r',
74
- rate=Where.gt(4.5),
74
+ rate=gt(4.5),
75
75
  movie_id=Distinct
76
76
  )
77
77
  )
@@ -92,8 +92,8 @@ query = Select('Movie m', title=Field,
92
92
  3.3 -- Optional conditions:
93
93
  ```
94
94
  OR=Options(
95
- genre=Where.eq("Sci-Fi"),
96
- awards=Where.like("Oscar")
95
+ genre=eq("Sci-Fi"),
96
+ awards=like("Oscar")
97
97
  )
98
98
  ```
99
99
  > Could be AND=Options(...)
@@ -105,7 +105,7 @@ based_on_book=Not.is_null()
105
105
 
106
106
  3.5 -- List of values
107
107
  ```
108
- hash_tag=Where.list(['space', 'monster', 'gore'])
108
+ hash_tag=contains(['space', 'monster', 'gore'])
109
109
  ```
110
110
 
111
111
  ---
@@ -117,7 +117,7 @@ hash_tag=Where.list(['space', 'monster', 'gore'])
117
117
  ```
118
118
  SelectIN(
119
119
  'Review r', movie=[GroupBy, Distinct],
120
- rate=Having.avg(Where.gt(4.5))
120
+ rate=Having.avg(gt(4.5))
121
121
  )
122
122
  ```
123
123
  ---
@@ -299,7 +299,7 @@ m = Select...
299
299
  ```
300
300
  best_movies = SelectIN(
301
301
  Review=Table('role'),
302
- rate=[GroupBy, Having.avg(Where.gt(4.5))]
302
+ rate=[GroupBy, Having.avg(gt(4.5))]
303
303
  )
304
304
  m1 = Select(
305
305
  Movie=Table('title,release_date'),
@@ -320,9 +320,9 @@ m2 = Select(
320
320
  Select(
321
321
  'Product',
322
322
  label=Case('price').when(
323
- Where.lt(50), 'cheap'
323
+ lt(50), 'cheap'
324
324
  ).when(
325
- Where.gt(100), 'expensive'
325
+ gt(100), 'expensive'
326
326
  ).else_value(
327
327
  'normal'
328
328
  )
@@ -360,3 +360,22 @@ m2 = Select(
360
360
  * Replace `YEAR` function with date range comparison.
361
361
 
362
362
  > The method allows you to select which rules you want to apply in the optimization...Or define your own rules!
363
+
364
+ ---
365
+
366
+ ### 12 - Adding multiple fields at once
367
+ ```
368
+ query = Select('post p')
369
+ query.add_fields(
370
+ 'user_id, created_at',
371
+ order_by=True, group_by=True
372
+ )
373
+ ```
374
+ ...is the same as...
375
+ ```
376
+ query = Select(
377
+ 'post p',
378
+ user_id=[Field, GroupBy, OrderBy],
379
+ created_at=[Field, GroupBy, OrderBy]
380
+ )
381
+ ```
@@ -0,0 +1,7 @@
1
+ sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
+ sql_blocks/sql_blocks.py,sha256=Fg7yPeASygx7c7Nct5yKurxRrnjVGsvp4RnR93Wwems,21519
3
+ sql_blocks-0.2.0.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
+ sql_blocks-0.2.0.dist-info/METADATA,sha256=CU4oSLqoycnvhkPROx_SSbj9zJjCwwz4JoePIgk4wSE,8794
5
+ sql_blocks-0.2.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
+ sql_blocks-0.2.0.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
+ sql_blocks-0.2.0.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
- sql_blocks/sql_blocks.py,sha256=wj54KGT9Bnbo9Jtyn_jA6lbHhgkmGirRUp6ZHq9ilZ8,20654
3
- sql_blocks-0.1.4.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
- sql_blocks-0.1.4.dist-info/METADATA,sha256=DWqKIgeFG_wjr8u4qusK-bcb_cgbxHXZ3DNFUXmMwKo,8503
5
- sql_blocks-0.1.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- sql_blocks-0.1.4.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
- sql_blocks-0.1.4.dist-info/RECORD,,