sql-blocks 0.2.3__tar.gz → 0.2.4__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.
- {sql_blocks-0.2.3/sql_blocks.egg-info → sql_blocks-0.2.4}/PKG-INFO +37 -1
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/README.md +37 -1
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/pyproject.toml +1 -1
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/setup.py +1 -1
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/sql_blocks/sql_blocks.py +116 -0
- {sql_blocks-0.2.3 → sql_blocks-0.2.4/sql_blocks.egg-info}/PKG-INFO +37 -1
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/LICENSE +0 -0
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/setup.cfg +0 -0
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/sql_blocks/__init__.py +0 -0
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/sql_blocks.egg-info/SOURCES.txt +0 -0
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/sql_blocks.egg-info/dependency_links.txt +0 -0
- {sql_blocks-0.2.3 → sql_blocks-0.2.4}/sql_blocks.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 0.2.
|
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
|
@@ -365,4 +365,40 @@ m2 = Select(
|
|
365
365
|
user_id=[Field, GroupBy, OrderBy],
|
366
366
|
created_at=[Field, GroupBy, OrderBy]
|
367
367
|
)
|
368
|
-
```
|
368
|
+
```
|
369
|
+
|
370
|
+
### 13 - Change parser engine
|
371
|
+
```
|
372
|
+
a, c, m = Select.parse(
|
373
|
+
"""
|
374
|
+
Actor(name, id ?age = 40)
|
375
|
+
<- Cast(actor_id, movie_id) ->
|
376
|
+
Movie(id ^title)
|
377
|
+
""",
|
378
|
+
Cypher
|
379
|
+
# ^^^ recognizes syntax like Neo4J queries
|
380
|
+
)
|
381
|
+
```
|
382
|
+
|
383
|
+
**print(a+c+m)**
|
384
|
+
```
|
385
|
+
SELECT
|
386
|
+
act.name,
|
387
|
+
mov.title
|
388
|
+
FROM
|
389
|
+
Cast cas
|
390
|
+
JOIN Movie mov ON (cas.movie_id = mov.id)
|
391
|
+
JOIN Actor act ON (cas.actor_id = act.id)
|
392
|
+
WHERE
|
393
|
+
act.age = 40
|
394
|
+
ORDER BY
|
395
|
+
mov.title
|
396
|
+
```
|
397
|
+
---
|
398
|
+
> **Separators and meaning:**
|
399
|
+
* `( )` Delimits a table and its fields
|
400
|
+
* `,` Separate fields
|
401
|
+
* `?` For simple conditions (> < = <>)
|
402
|
+
* `<-` connects to the table on the left
|
403
|
+
* `->` connects to the table on the right
|
404
|
+
* `^` Put the field in the ORDER BY clause
|
@@ -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
|
+
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|