sql-blocks 0.2.4__tar.gz → 0.2.6__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.2.4
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sql_blocks"
3
- version = "0.2.4"
3
+ version = "0.2.6"
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 = '0.2.4',
6
+ version = '0.2.6',
7
7
  author = 'Júlio Cascalles',
8
8
  author_email = 'julio.cascalles@outlook.com',
9
9
  packages = ['sql_blocks'],
@@ -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
- if not self.REGEX:
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
- pk_field = last.values[SELECT][-1].split('.')[-1]
548
- last.delete(pk_field, [SELECT])
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
- pk_field, token = token, pk_field
552
- last.key_field = pk_field
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] = (pk_field, token)
581
+ ForeignKey.references[k] = (token, pk_field)
555
582
  self.join_type = JoinType.INNER
556
583
 
557
584
  def eval(self, txt: str):
558
- self.join_type = JoinType.INNER
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 == '(' and self.join_type != JoinType.INNER:
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.REGEX['separator'].split( re.sub(r'\s+', '', txt) ):
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.4
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
File without changes
File without changes
File without changes