sql-blocks 0.2.3__py3-none-any.whl → 0.2.4__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
@@ -567,6 +567,122 @@ class Cypher(Parser):
567
567
  else:
568
568
  self.method = self.TOKEN_METHODS.get(token)
569
569
 
570
+ # ----------------------------
571
+ class MongoParser(Parser):
572
+ REGEX = {}
573
+
574
+ def prepare(self):
575
+ self.REGEX['separator'] = re.compile(r'([({[\]},)])')
576
+
577
+ def new_query(self, token: str):
578
+ if not token:
579
+ return
580
+ *table, function = token.split('.')
581
+ self.param_type = self.PARAM_BY_FUNCTION.get(function)
582
+ if not self.param_type:
583
+ raise SyntaxError(f'Unknown function {function}')
584
+ if table and table[0]:
585
+ self.queries.append( self.class_type(table[-1]) )
586
+
587
+ def param_is_where(self) -> bool:
588
+ return self.param_type == Where or isinstance(self.param_type, Where)
589
+
590
+ def next_param(self, token: str):
591
+ if self.param_type == GroupBy:
592
+ self.param_type = Field
593
+ self.get_param(token)
594
+
595
+ def get_param(self, token: str):
596
+ if not ':' in token:
597
+ return
598
+ field, value = token.split(':')
599
+ is_function = field.startswith('$')
600
+ if not value and not is_function:
601
+ if self.param_is_where():
602
+ self.last_field = field
603
+ return
604
+ if self.param_is_where():
605
+ if is_function:
606
+ function = field
607
+ field = self.last_field
608
+ self.last_field = ''
609
+ else:
610
+ function = '$eq'
611
+ if '"' in value:
612
+ value = value.replace('"', '')
613
+ elif value and value[0].isnumeric():
614
+ numeric_type = float if len(value.split('.')) == 2 else int
615
+ value = numeric_type(value)
616
+ self.param_type = self.CONDITIONS[function](value)
617
+ if function == '$or':
618
+ return
619
+ elif self.param_type == GroupBy:
620
+ if field != '_id':
621
+ return
622
+ field = re.sub('"|[$]', '', value)
623
+ elif self.param_type == OrderBy and value == '-1':
624
+ OrderBy.sort = SortType.DESC
625
+ elif field.startswith('$'):
626
+ field = '{}({})'.format(
627
+ field.replace('$', ''), value
628
+ )
629
+ if self.where_list is not None and self.param_is_where():
630
+ self.where_list[field] = self.param_type
631
+ return
632
+ self.param_type.add(field, self.queries[-1])
633
+
634
+ def close_brackets(self, token: str):
635
+ self.brackets[token] -= 1
636
+ if self.param_is_where() and self.brackets[token] == 0:
637
+ if self.where_list is not None:
638
+ Options(**self.where_list).add('OR', self.queries[-1])
639
+ self.where_list = None
640
+ if token == '{':
641
+ self.param_type = Field
642
+
643
+ def begin_conditions(self, value: str):
644
+ self.where_list = {}
645
+ return Where
646
+
647
+ def increment_brackets(self, value: str):
648
+ self.brackets[value] += 1
649
+
650
+ def eval(self, txt: str):
651
+ self.method = self.new_query
652
+ self.last_field = ''
653
+ self.where_list = None
654
+ self.PARAM_BY_FUNCTION = {
655
+ 'find': Where, 'aggregate': GroupBy, 'sort': OrderBy
656
+ }
657
+ BRACKET_PAIR = {'}': '{', ']': '['}
658
+ self.brackets = {char: 0 for char in BRACKET_PAIR.values()}
659
+ self.CONDITIONS = {
660
+ '$in': lambda value: contains(value),
661
+ '$gt': lambda value: gt(value),
662
+ '$gte' : lambda value: gte(value),
663
+ '$lt': lambda value: lt(value),
664
+ '$lte' : lambda value: lte(value),
665
+ '$eq': lambda value: eq(value),
666
+ '$ne': lambda value: Not.eq(value),
667
+ '$or': self.begin_conditions,
668
+ }
669
+ self.TOKEN_METHODS = {
670
+ '{': self.get_param, ',': self.next_param, ')': self.new_query,
671
+ }
672
+ for token in self.REGEX['separator'].split( re.sub(r'\s+', '', txt) ):
673
+ if not token:
674
+ continue
675
+ if self.method:
676
+ self.method(token)
677
+ if token in self.brackets:
678
+ self.increment_brackets(token)
679
+ elif token in BRACKET_PAIR:
680
+ self.close_brackets(
681
+ BRACKET_PAIR[token]
682
+ )
683
+ self.method = self.TOKEN_METHODS.get(token)
684
+ # ----------------------------
685
+
570
686
 
571
687
  class JoinType(Enum):
572
688
  INNER = ''
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql_blocks
3
- Version: 0.2.3
3
+ Version: 0.2.4
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
@@ -381,3 +381,39 @@ m2 = Select(
381
381
  created_at=[Field, GroupBy, OrderBy]
382
382
  )
383
383
  ```
384
+
385
+ ### 13 - Change parser engine
386
+ ```
387
+ a, c, m = Select.parse(
388
+ """
389
+ Actor(name, id ?age = 40)
390
+ <- Cast(actor_id, movie_id) ->
391
+ Movie(id ^title)
392
+ """,
393
+ Cypher
394
+ # ^^^ recognizes syntax like Neo4J queries
395
+ )
396
+ ```
397
+
398
+ **print(a+c+m)**
399
+ ```
400
+ SELECT
401
+ act.name,
402
+ mov.title
403
+ FROM
404
+ Cast cas
405
+ JOIN Movie mov ON (cas.movie_id = mov.id)
406
+ JOIN Actor act ON (cas.actor_id = act.id)
407
+ WHERE
408
+ act.age = 40
409
+ ORDER BY
410
+ mov.title
411
+ ```
412
+ ---
413
+ > **Separators and meaning:**
414
+ * `( )` Delimits a table and its fields
415
+ * `,` Separate fields
416
+ * `?` For simple conditions (> < = <>)
417
+ * `<-` connects to the table on the left
418
+ * `->` connects to the table on the right
419
+ * `^` Put the field in the ORDER BY clause
@@ -0,0 +1,7 @@
1
+ sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
+ sql_blocks/sql_blocks.py,sha256=DJN_xFMXH9apG4304PtLyVSep7Kz32nyTD5-lSWs6ts,28659
3
+ sql_blocks-0.2.4.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
+ sql_blocks-0.2.4.dist-info/METADATA,sha256=kNLOaXxpoPXmHiq9uRpWnVgEAxPnQH3tlmiJ1f3cYP8,9675
5
+ sql_blocks-0.2.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
+ sql_blocks-0.2.4.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
+ sql_blocks-0.2.4.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
- sql_blocks/sql_blocks.py,sha256=xWP7coiy5Tj8YU_WgtkN8J8tc9-0_BaE-bYljPdEp6o,24361
3
- sql_blocks-0.2.3.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
- sql_blocks-0.2.3.dist-info/METADATA,sha256=0bRpoB8KehBZ40kf-pXyOvrVcozTUZo-BsC3Aq5xn2I,8892
5
- sql_blocks-0.2.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- sql_blocks-0.2.3.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
- sql_blocks-0.2.3.dist-info/RECORD,,