sql-blocks 0.2.4__py3-none-any.whl → 0.2.6__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 +68 -23
- {sql_blocks-0.2.4.dist-info → sql_blocks-0.2.6.dist-info}/METADATA +1 -1
- sql_blocks-0.2.6.dist-info/RECORD +7 -0
- sql_blocks-0.2.4.dist-info/RECORD +0 -7
- {sql_blocks-0.2.4.dist-info → sql_blocks-0.2.6.dist-info}/LICENSE +0 -0
- {sql_blocks-0.2.4.dist-info → sql_blocks-0.2.6.dist-info}/WHEEL +0 -0
- {sql_blocks-0.2.4.dist-info → sql_blocks-0.2.6.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -9,7 +9,7 @@ DISTINCT_PREFX = '(DISTINCT|distinct)'
|
|
9
9
|
KEYWORD = {
|
10
10
|
'SELECT': (',{}', 'SELECT *', DISTINCT_PREFX),
|
11
11
|
'FROM': ('{}', '', PATTERN_SUFFIX),
|
12
|
-
'WHERE': ('{}AND ', '', ''),
|
12
|
+
'WHERE': ('{}AND ', '', r'["\']'),
|
13
13
|
'GROUP BY': (',{}', '', PATTERN_SUFFIX),
|
14
14
|
'ORDER BY': (',{}', '', PATTERN_SUFFIX),
|
15
15
|
'LIMIT': (' ', '', ''),
|
@@ -69,27 +69,32 @@ class SQLObject:
|
|
69
69
|
return KEYWORD[key][0].format(appendix.get(key, ''))
|
70
70
|
|
71
71
|
def diff(self, key: str, search_list: list, exact: bool=False) -> set:
|
72
|
+
def disassemble(source: list) -> list:
|
73
|
+
result = []
|
74
|
+
for fld in source:
|
75
|
+
result += re.split(r'([=()]|<>|\s+ON\s+|\s+on\s+)', fld)
|
76
|
+
return result
|
72
77
|
def cleanup(fld: str) -> str:
|
73
78
|
if exact:
|
74
79
|
fld = fld.lower()
|
75
80
|
return fld.strip()
|
76
81
|
def is_named_field(fld: str) -> bool:
|
77
82
|
return key == SELECT and re.search(' as | AS ', fld)
|
78
|
-
pattern = KEYWORD[key][2]
|
79
|
-
if exact:
|
80
|
-
if key == WHERE:
|
81
|
-
pattern = ' '
|
82
|
-
pattern += f'|{PATTERN_PREFIX}'
|
83
|
-
separator = self.get_separator(key)
|
84
83
|
def field_set(source: list) -> set:
|
85
84
|
return set(
|
86
85
|
(
|
87
86
|
fld if is_named_field(fld) else
|
88
87
|
re.sub(pattern, '', cleanup(fld))
|
89
88
|
)
|
90
|
-
for string in source
|
89
|
+
for string in disassemble(source)
|
91
90
|
for fld in re.split(separator, string)
|
92
91
|
)
|
92
|
+
pattern = KEYWORD[key][2]
|
93
|
+
if exact:
|
94
|
+
if key == WHERE:
|
95
|
+
pattern = ' '
|
96
|
+
pattern += f'|{PATTERN_PREFIX}'
|
97
|
+
separator = self.get_separator(key)
|
93
98
|
s1 = field_set(search_list)
|
94
99
|
s2 = field_set(self.values.get(key, []))
|
95
100
|
if exact:
|
@@ -421,14 +426,30 @@ class Parser:
|
|
421
426
|
|
422
427
|
def __init__(self, txt: str, class_type):
|
423
428
|
self.queries = []
|
424
|
-
|
425
|
-
self.prepare()
|
429
|
+
self.prepare()
|
426
430
|
self.class_type = class_type
|
427
431
|
self.eval(txt)
|
428
432
|
|
429
433
|
def eval(self, txt: str):
|
430
434
|
...
|
431
435
|
|
436
|
+
@staticmethod
|
437
|
+
def remove_spaces(script: str) -> str:
|
438
|
+
is_string = False
|
439
|
+
result = []
|
440
|
+
for token in re.split(r'(")', script):
|
441
|
+
if token == '"':
|
442
|
+
is_string = not is_string
|
443
|
+
if not is_string:
|
444
|
+
token = re.sub(r'\s+', '', token)
|
445
|
+
result.append(token)
|
446
|
+
return ''.join(result)
|
447
|
+
|
448
|
+
def get_tokens(self, txt: str) -> list:
|
449
|
+
return self.REGEX['separator'].split(
|
450
|
+
self.remove_spaces(txt)
|
451
|
+
)
|
452
|
+
|
432
453
|
|
433
454
|
class SQLParser(Parser):
|
434
455
|
REGEX = {}
|
@@ -506,17 +527,18 @@ class SQLParser(Parser):
|
|
506
527
|
|
507
528
|
class Cypher(Parser):
|
508
529
|
REGEX = {}
|
509
|
-
TOKEN_METHODS = {}
|
510
530
|
|
511
531
|
def prepare(self):
|
512
|
-
self.REGEX['separator'] = re.compile(r'([(,?)^]|->|<-)')
|
532
|
+
self.REGEX['separator'] = re.compile(r'([(,?)^{}[\]]|->|<-)')
|
513
533
|
self.REGEX['condition'] = re.compile(r'(^\w+)|([<>=])')
|
534
|
+
self.join_type = JoinType.INNER
|
514
535
|
self.TOKEN_METHODS = {
|
515
536
|
'(': self.add_field, '?': self.add_where,
|
516
537
|
',': self.add_field, '^': self.add_order,
|
517
538
|
')': self.new_query, '->': self.left_ftable,
|
518
539
|
'<-': self.right_ftable,
|
519
540
|
}
|
541
|
+
self.method = self.new_query
|
520
542
|
|
521
543
|
def new_query(self, token: str):
|
522
544
|
if token.isidentifier():
|
@@ -542,31 +564,54 @@ class Cypher(Parser):
|
|
542
564
|
self.new_query(token)
|
543
565
|
self.join_type = JoinType.RIGHT
|
544
566
|
|
545
|
-
def add_foreign_key(self, token: str):
|
567
|
+
def add_foreign_key(self, token: str, pk_field: str=''):
|
546
568
|
curr, last = [self.queries[i] for i in (-1, -2)]
|
547
|
-
|
548
|
-
|
569
|
+
if not pk_field:
|
570
|
+
if not last.values.get(SELECT):
|
571
|
+
return
|
572
|
+
pk_field = last.values[SELECT][-1].split('.')[-1]
|
573
|
+
last.delete(pk_field, [SELECT])
|
549
574
|
if self.join_type == JoinType.RIGHT:
|
550
575
|
curr, last = last, curr
|
551
|
-
|
552
|
-
|
576
|
+
if '{}' in token:
|
577
|
+
token = token.format(
|
578
|
+
curr.table_name.lower()
|
579
|
+
)
|
553
580
|
k = ForeignKey.get_key(last, curr)
|
554
|
-
ForeignKey.references[k] = (
|
581
|
+
ForeignKey.references[k] = (token, pk_field)
|
555
582
|
self.join_type = JoinType.INNER
|
556
583
|
|
557
584
|
def eval(self, txt: str):
|
558
|
-
|
559
|
-
self.method = self.new_query
|
560
|
-
for token in self.REGEX['separator'].split( re.sub(r'\s+', '', txt) ):
|
585
|
+
for token in self.get_tokens(txt):
|
561
586
|
if not token:
|
562
587
|
continue
|
563
588
|
if self.method:
|
564
589
|
self.method(token)
|
565
|
-
if token
|
590
|
+
if token in '([' and self.join_type != JoinType.INNER:
|
566
591
|
self.method = self.add_foreign_key
|
567
592
|
else:
|
568
593
|
self.method = self.TOKEN_METHODS.get(token)
|
569
594
|
|
595
|
+
class Neo4JParser(Cypher):
|
596
|
+
def prepare(self):
|
597
|
+
super().prepare()
|
598
|
+
self.TOKEN_METHODS = {
|
599
|
+
'(': self.new_query, '{': self.add_where,
|
600
|
+
'->': self.left_ftable, '<-': self.right_ftable,
|
601
|
+
'[': self.new_query
|
602
|
+
}
|
603
|
+
self.method = None
|
604
|
+
|
605
|
+
def new_query(self, token: str):
|
606
|
+
super().new_query(token.split(':')[-1])
|
607
|
+
|
608
|
+
def add_where(self, token: str):
|
609
|
+
super().add_where(token.replace(':', '='))
|
610
|
+
|
611
|
+
def add_foreign_key(self, token: str, pk_field: str='') -> tuple:
|
612
|
+
self.new_query(token)
|
613
|
+
return super().add_foreign_key('{}_id', 'id')
|
614
|
+
|
570
615
|
# ----------------------------
|
571
616
|
class MongoParser(Parser):
|
572
617
|
REGEX = {}
|
@@ -669,7 +714,7 @@ class MongoParser(Parser):
|
|
669
714
|
self.TOKEN_METHODS = {
|
670
715
|
'{': self.get_param, ',': self.next_param, ')': self.new_query,
|
671
716
|
}
|
672
|
-
for token in self.
|
717
|
+
for token in self.get_tokens(txt):
|
673
718
|
if not token:
|
674
719
|
continue
|
675
720
|
if self.method:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.6
|
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=IT3XUhBdOA1MawoSaw-oMm1v4yv16fDwqcu21sGnIQs,30086
|
3
|
+
sql_blocks-0.2.6.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-0.2.6.dist-info/METADATA,sha256=4A--jCZFBGeVn_fXcF41szBc_4ReMJrVKr9WWqJZnZA,9675
|
5
|
+
sql_blocks-0.2.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-0.2.6.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-0.2.6.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
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,,
|
File without changes
|
File without changes
|
File without changes
|