sql-blocks 0.2.6__py3-none-any.whl → 0.2.9__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 +285 -57
- {sql_blocks-0.2.6.dist-info → sql_blocks-0.2.9.dist-info}/METADATA +1 -1
- sql_blocks-0.2.9.dist-info/RECORD +7 -0
- sql_blocks-0.2.6.dist-info/RECORD +0 -7
- {sql_blocks-0.2.6.dist-info → sql_blocks-0.2.9.dist-info}/LICENSE +0 -0
- {sql_blocks-0.2.6.dist-info → sql_blocks-0.2.9.dist-info}/WHEEL +0 -0
- {sql_blocks-0.2.6.dist-info → sql_blocks-0.2.9.dist-info}/top_level.txt +0 -0
sql_blocks/sql_blocks.py
CHANGED
@@ -7,20 +7,18 @@ PATTERN_SUFFIX = '( [A-Za-z_]+)'
|
|
7
7
|
DISTINCT_PREFX = '(DISTINCT|distinct)'
|
8
8
|
|
9
9
|
KEYWORD = {
|
10
|
-
'SELECT':
|
11
|
-
'FROM':
|
12
|
-
'WHERE':
|
13
|
-
'GROUP BY': (',{}',
|
14
|
-
'ORDER BY': (',{}',
|
15
|
-
'LIMIT':
|
16
|
-
}
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# |
|
23
|
-
# +-------- separator
|
10
|
+
'SELECT': (',{}', DISTINCT_PREFX),
|
11
|
+
'FROM': ('{}', PATTERN_SUFFIX),
|
12
|
+
'WHERE': ('{}AND ', ''),
|
13
|
+
'GROUP BY': (',{}', PATTERN_SUFFIX),
|
14
|
+
'ORDER BY': (',{}', PATTERN_SUFFIX),
|
15
|
+
'LIMIT': (' ', ''),
|
16
|
+
}
|
17
|
+
# ^ ^
|
18
|
+
# | |
|
19
|
+
# | +----- pattern to compare fields
|
20
|
+
# |
|
21
|
+
# +-------- separator
|
24
22
|
|
25
23
|
SELECT, FROM, WHERE, GROUP_BY, ORDER_BY, LIMIT = KEYWORD.keys()
|
26
24
|
USUAL_KEYS = [SELECT, WHERE, GROUP_BY, ORDER_BY, LIMIT]
|
@@ -70,6 +68,8 @@ class SQLObject:
|
|
70
68
|
|
71
69
|
def diff(self, key: str, search_list: list, exact: bool=False) -> set:
|
72
70
|
def disassemble(source: list) -> list:
|
71
|
+
if not exact:
|
72
|
+
return source
|
73
73
|
result = []
|
74
74
|
for fld in source:
|
75
75
|
result += re.split(r'([=()]|<>|\s+ON\s+|\s+on\s+)', fld)
|
@@ -89,10 +89,10 @@ class SQLObject:
|
|
89
89
|
for string in disassemble(source)
|
90
90
|
for fld in re.split(separator, string)
|
91
91
|
)
|
92
|
-
pattern = KEYWORD[key][
|
92
|
+
pattern = KEYWORD[key][1]
|
93
93
|
if exact:
|
94
94
|
if key == WHERE:
|
95
|
-
pattern = ' '
|
95
|
+
pattern = r'["\']| '
|
96
96
|
pattern += f'|{PATTERN_PREFIX}'
|
97
97
|
separator = self.get_separator(key)
|
98
98
|
s1 = field_set(search_list)
|
@@ -418,6 +418,222 @@ class Rule:
|
|
418
418
|
def apply(cls, target: 'Select'):
|
419
419
|
...
|
420
420
|
|
421
|
+
class QueryLanguage:
|
422
|
+
pattern = '{select}{_from}{where}{group_by}{order_by}'
|
423
|
+
has_default = {key: bool(key == SELECT) for key in KEYWORD}
|
424
|
+
|
425
|
+
@staticmethod
|
426
|
+
def remove_alias(fld: str) -> str:
|
427
|
+
return ''.join(re.split(r'\w+[.]', fld))
|
428
|
+
|
429
|
+
def join_with_tabs(self, values: list, sep: str='') -> str:
|
430
|
+
sep = sep + self.TABULATION
|
431
|
+
return sep.join(v for v in values if v)
|
432
|
+
|
433
|
+
def add_field(self, values: list) -> str:
|
434
|
+
if not values:
|
435
|
+
return '*'
|
436
|
+
return self.join_with_tabs(values, ',')
|
437
|
+
|
438
|
+
def get_tables(self, values: list) -> str:
|
439
|
+
return self.join_with_tabs(values)
|
440
|
+
|
441
|
+
def extract_conditions(self, values: list) -> str:
|
442
|
+
return self.join_with_tabs(values, ' AND ')
|
443
|
+
|
444
|
+
def sort_by(self, values: list) -> str:
|
445
|
+
return self.join_with_tabs(values)
|
446
|
+
|
447
|
+
def set_group(self, values: list) -> str:
|
448
|
+
return self.join_with_tabs(values, ',')
|
449
|
+
|
450
|
+
def __init__(self, target: 'Select'):
|
451
|
+
self.KEYWORDS = [SELECT, FROM, WHERE, GROUP_BY, ORDER_BY]
|
452
|
+
self.TABULATION = '\n\t' if target.break_lines else ' '
|
453
|
+
self.LINE_BREAK = '\n' if target.break_lines else ' '
|
454
|
+
self.TOKEN_METHODS = {
|
455
|
+
SELECT: self.add_field, FROM: self.get_tables,
|
456
|
+
WHERE: self.extract_conditions,
|
457
|
+
ORDER_BY: self.sort_by, GROUP_BY: self.set_group,
|
458
|
+
}
|
459
|
+
self.result = {}
|
460
|
+
self.target = target
|
461
|
+
|
462
|
+
def pair(self, key: str) -> str:
|
463
|
+
if key == FROM:
|
464
|
+
return '_from'
|
465
|
+
return key.lower().replace(' ', '_')
|
466
|
+
|
467
|
+
def prefix(self, key: str) -> str:
|
468
|
+
return self.LINE_BREAK + key + self.TABULATION
|
469
|
+
|
470
|
+
def convert(self) -> str:
|
471
|
+
for key in self.KEYWORDS:
|
472
|
+
method = self.TOKEN_METHODS.get(key)
|
473
|
+
ref = self.pair(key)
|
474
|
+
values = self.target.values.get(key, [])
|
475
|
+
if not method or (not values and not self.has_default[key]):
|
476
|
+
self.result[ref] = ''
|
477
|
+
continue
|
478
|
+
text = self.prefix(key) + method(values)
|
479
|
+
self.result[ref] = text
|
480
|
+
return self.pattern.format(**self.result).strip()
|
481
|
+
|
482
|
+
class MongoDBLanguage(QueryLanguage):
|
483
|
+
pattern = '{_from}.{function}({where}{select}{group_by}){order_by}'
|
484
|
+
has_default = {key: False for key in KEYWORD}
|
485
|
+
LOGICAL_OP_TO_MONGO_FUNC = {
|
486
|
+
'>': '$gt', '>=': '$gte',
|
487
|
+
'<': '$lt', '<=': '$lte',
|
488
|
+
'=': '$eq', '<>': '$ne',
|
489
|
+
}
|
490
|
+
OPERATORS = '|'.join(op for op in LOGICAL_OP_TO_MONGO_FUNC)
|
491
|
+
REGEX = {
|
492
|
+
'options': re.compile(r'\s+or\s+|\s+OR\s+'),
|
493
|
+
'condition': re.compile(fr'({OPERATORS})')
|
494
|
+
}
|
495
|
+
|
496
|
+
def join_with_tabs(self, values: list, sep: str=',') -> str:
|
497
|
+
def format_field(fld):
|
498
|
+
return '{indent}{fld}'.format(
|
499
|
+
fld=self.remove_alias(fld),
|
500
|
+
indent=self.TABULATION
|
501
|
+
)
|
502
|
+
return '{begin}{content}{line_break}{end}'.format(
|
503
|
+
begin='{',
|
504
|
+
content= sep.join(
|
505
|
+
format_field(fld) for fld in values if fld
|
506
|
+
),
|
507
|
+
end='}', line_break=self.LINE_BREAK,
|
508
|
+
)
|
509
|
+
|
510
|
+
def add_field(self, values: list) -> str:
|
511
|
+
if self.result['function'] == 'aggregate':
|
512
|
+
return ''
|
513
|
+
return ',{content}'.format(
|
514
|
+
content=self.join_with_tabs([f'{fld}: 1' for fld in values]),
|
515
|
+
)
|
516
|
+
|
517
|
+
def get_tables(self, values: list) -> str:
|
518
|
+
return values[0].split()[0].lower()
|
519
|
+
|
520
|
+
@classmethod
|
521
|
+
def mongo_where_list(cls, values: list) -> list:
|
522
|
+
OR_REGEX = cls.REGEX['options']
|
523
|
+
where_list = []
|
524
|
+
for condition in values:
|
525
|
+
if OR_REGEX.findall(condition):
|
526
|
+
condition = re.sub('[()]', '', condition)
|
527
|
+
expr = '{begin}$or: [{content}]{end}'.format(
|
528
|
+
content=','.join(
|
529
|
+
cls.mongo_where_list( OR_REGEX.split(condition) )
|
530
|
+
), begin='{', end='}',
|
531
|
+
)
|
532
|
+
where_list.append(expr)
|
533
|
+
continue
|
534
|
+
tokens = cls.REGEX['condition'].split(
|
535
|
+
cls.remove_alias(condition)
|
536
|
+
)
|
537
|
+
tokens = [t.strip() for t in tokens if t]
|
538
|
+
field, *op, const = tokens
|
539
|
+
op = ''.join(op)
|
540
|
+
expr = '{begin}{op}:{const}{end}'.format(
|
541
|
+
begin='{', const=const, end='}',
|
542
|
+
op=cls.LOGICAL_OP_TO_MONGO_FUNC[op],
|
543
|
+
)
|
544
|
+
where_list.append(f'{field}:{expr}')
|
545
|
+
return where_list
|
546
|
+
|
547
|
+
def extract_conditions(self, values: list) -> str:
|
548
|
+
return self.join_with_tabs(
|
549
|
+
self.mongo_where_list(values)
|
550
|
+
)
|
551
|
+
|
552
|
+
def sort_by(self, values: list) -> str:
|
553
|
+
return ".sort({begin}{indent}{field}:{flag}{line_break}{end})".format(
|
554
|
+
begin='{', field=self.remove_alias(values[0].split()[0]),
|
555
|
+
flag=-1 if OrderBy.sort == SortType.DESC else 1,
|
556
|
+
end='}', indent=self.TABULATION, line_break=self.LINE_BREAK,
|
557
|
+
)
|
558
|
+
|
559
|
+
def set_group(self, values: list) -> str:
|
560
|
+
self.result['function'] = 'aggregate'
|
561
|
+
return '{"$group" : {_id:"$%%", count:{$sum:1}}}'.replace(
|
562
|
+
'%%', self.remove_alias( values[0] )
|
563
|
+
)
|
564
|
+
|
565
|
+
def __init__(self, target: 'Select'):
|
566
|
+
super().__init__(target)
|
567
|
+
self.result['function'] = 'find'
|
568
|
+
self.KEYWORDS = [GROUP_BY, SELECT, FROM, WHERE, ORDER_BY]
|
569
|
+
|
570
|
+
def prefix(self, key: str):
|
571
|
+
return ''
|
572
|
+
|
573
|
+
|
574
|
+
class Neo4JLanguage(QueryLanguage):
|
575
|
+
pattern = 'MATCH {_from} RETURN {aliases}'
|
576
|
+
has_default = {key: False for key in KEYWORD}
|
577
|
+
|
578
|
+
def add_field(self, values: list) -> str:
|
579
|
+
return ''
|
580
|
+
|
581
|
+
def get_tables(self, values: list) -> str:
|
582
|
+
NODE_FORMAT = dict(
|
583
|
+
left='({}:{}{})<-',
|
584
|
+
core='[{}:{}{}]',
|
585
|
+
right='->({}:{}{})'
|
586
|
+
)
|
587
|
+
nodes = {k: '' for k in NODE_FORMAT}
|
588
|
+
for txt in values:
|
589
|
+
found = re.search(
|
590
|
+
r'^(left|right)\s+', txt, re.IGNORECASE
|
591
|
+
)
|
592
|
+
pos = 'core'
|
593
|
+
if found:
|
594
|
+
start, end = found.span()
|
595
|
+
pos = txt[start:end-1].lower()
|
596
|
+
tokens = re.split(r'JOIN\s+|ON\s+', txt[end:])
|
597
|
+
txt = tokens[1].strip()
|
598
|
+
table_name, *alias = txt.split()
|
599
|
+
if alias:
|
600
|
+
alias = alias[0]
|
601
|
+
else:
|
602
|
+
alias = SQLObject.ALIAS_FUNC(table_name)
|
603
|
+
condition = self.aliases.get(alias, '')
|
604
|
+
if not condition:
|
605
|
+
self.aliases[alias] = ''
|
606
|
+
nodes[pos] = NODE_FORMAT[pos].format(alias, table_name, condition)
|
607
|
+
self.result['aliases'] = ','.join(self.aliases.keys())
|
608
|
+
return '{left}{core}{right}'.format(**nodes)
|
609
|
+
|
610
|
+
def extract_conditions(self, values: list) -> str:
|
611
|
+
for condition in values:
|
612
|
+
other_comparisions = any(
|
613
|
+
char in condition for char in '<>%'
|
614
|
+
)
|
615
|
+
if '=' not in condition or other_comparisions:
|
616
|
+
raise NotImplementedError('Only comparisons with equality are available for now.')
|
617
|
+
alias, field, const = re.split(r'[.=]', condition)
|
618
|
+
begin, end = '{', '}'
|
619
|
+
self.aliases[alias] = f'{begin}{field}:{const}{end}'
|
620
|
+
return '' # --- WHERE [*other_comparisions*] ...
|
621
|
+
|
622
|
+
def sort_by(self, values: list) -> str:
|
623
|
+
return ''
|
624
|
+
|
625
|
+
def set_group(self, values: list) -> str:
|
626
|
+
return ''
|
627
|
+
|
628
|
+
def __init__(self, target: 'Select'):
|
629
|
+
super().__init__(target)
|
630
|
+
self.aliases = {}
|
631
|
+
self.KEYWORDS = [WHERE, FROM]
|
632
|
+
|
633
|
+
def prefix(self, key: str):
|
634
|
+
return ''
|
635
|
+
|
636
|
+
|
421
637
|
class Parser:
|
422
638
|
REGEX = {}
|
423
639
|
|
@@ -451,6 +667,13 @@ class Parser:
|
|
451
667
|
)
|
452
668
|
|
453
669
|
|
670
|
+
class JoinType(Enum):
|
671
|
+
INNER = ''
|
672
|
+
LEFT = 'LEFT '
|
673
|
+
RIGHT = 'RIGHT '
|
674
|
+
FULL = 'FULL '
|
675
|
+
|
676
|
+
|
454
677
|
class SQLParser(Parser):
|
455
678
|
REGEX = {}
|
456
679
|
|
@@ -535,14 +758,16 @@ class Cypher(Parser):
|
|
535
758
|
self.TOKEN_METHODS = {
|
536
759
|
'(': self.add_field, '?': self.add_where,
|
537
760
|
',': self.add_field, '^': self.add_order,
|
538
|
-
')': self.new_query, '
|
539
|
-
'
|
761
|
+
')': self.new_query, '<-': self.left_ftable,
|
762
|
+
'->': self.right_ftable,
|
540
763
|
}
|
541
764
|
self.method = self.new_query
|
542
765
|
|
543
|
-
def new_query(self, token: str):
|
766
|
+
def new_query(self, token: str, join_type = JoinType.INNER):
|
544
767
|
if token.isidentifier():
|
545
|
-
|
768
|
+
query = self.class_type(token)
|
769
|
+
self.queries.append(query)
|
770
|
+
query.join_type = join_type
|
546
771
|
|
547
772
|
def add_where(self, token: str):
|
548
773
|
field, *condition = [
|
@@ -557,59 +782,75 @@ class Cypher(Parser):
|
|
557
782
|
FieldList(token, [Field]).add('', self.queries[-1])
|
558
783
|
|
559
784
|
def left_ftable(self, token: str):
|
785
|
+
if self.queries:
|
786
|
+
self.queries[-1].join_type = JoinType.LEFT
|
560
787
|
self.new_query(token)
|
561
|
-
self.join_type = JoinType.LEFT
|
562
788
|
|
563
789
|
def right_ftable(self, token: str):
|
564
|
-
self.new_query(token)
|
565
|
-
self.join_type = JoinType.RIGHT
|
790
|
+
self.new_query(token, JoinType.RIGHT)
|
566
791
|
|
567
792
|
def add_foreign_key(self, token: str, pk_field: str=''):
|
568
793
|
curr, last = [self.queries[i] for i in (-1, -2)]
|
569
794
|
if not pk_field:
|
570
795
|
if not last.values.get(SELECT):
|
571
|
-
|
796
|
+
raise IndexError(f'Primary Key not found for {last.table_name}.')
|
572
797
|
pk_field = last.values[SELECT][-1].split('.')[-1]
|
573
798
|
last.delete(pk_field, [SELECT])
|
574
|
-
if self.join_type == JoinType.RIGHT:
|
575
|
-
curr, last = last, curr
|
576
799
|
if '{}' in token:
|
577
|
-
|
800
|
+
foreign_fld = token.format(
|
801
|
+
last.table_name.lower()
|
802
|
+
if last.join_type == JoinType.LEFT else
|
578
803
|
curr.table_name.lower()
|
579
804
|
)
|
580
|
-
|
581
|
-
|
582
|
-
|
805
|
+
else:
|
806
|
+
if not curr.values.get(SELECT):
|
807
|
+
raise IndexError(f'Foreign Key not found for {curr.table_name}.')
|
808
|
+
foreign_fld = curr.values[SELECT][0].split('.')[-1]
|
809
|
+
curr.delete(foreign_fld, [SELECT])
|
810
|
+
if curr.join_type == JoinType.RIGHT:
|
811
|
+
curr, last = last, curr
|
812
|
+
k = ForeignKey.get_key(curr, last)
|
813
|
+
ForeignKey.references[k] = (foreign_fld, pk_field)
|
814
|
+
|
815
|
+
def fk_charset(self) -> str:
|
816
|
+
return '(['
|
583
817
|
|
584
818
|
def eval(self, txt: str):
|
819
|
+
# ====================================
|
820
|
+
def has_side_table() -> bool:
|
821
|
+
count = 0 if len(self.queries) < 2 else sum(
|
822
|
+
q.join_type != JoinType.INNER
|
823
|
+
for q in self.queries[-2:]
|
824
|
+
)
|
825
|
+
return count > 0
|
826
|
+
# -----------------------------------
|
585
827
|
for token in self.get_tokens(txt):
|
586
|
-
if not token:
|
828
|
+
if not token or (token in '([' and self.method):
|
587
829
|
continue
|
588
830
|
if self.method:
|
589
831
|
self.method(token)
|
590
|
-
if token in '
|
591
|
-
self.
|
592
|
-
|
593
|
-
|
832
|
+
if token in ')]' and has_side_table():
|
833
|
+
self.add_foreign_key('')
|
834
|
+
self.method = self.TOKEN_METHODS.get(token)
|
835
|
+
# ====================================
|
594
836
|
|
595
837
|
class Neo4JParser(Cypher):
|
596
838
|
def prepare(self):
|
597
839
|
super().prepare()
|
598
840
|
self.TOKEN_METHODS = {
|
599
841
|
'(': self.new_query, '{': self.add_where,
|
600
|
-
'
|
842
|
+
'<-': self.left_ftable, '->': self.right_ftable,
|
601
843
|
'[': self.new_query
|
602
844
|
}
|
603
845
|
self.method = None
|
604
846
|
|
605
|
-
def new_query(self, token: str):
|
606
|
-
super().new_query(token.split(':')[-1])
|
847
|
+
def new_query(self, token: str, join_type = JoinType.INNER):
|
848
|
+
super().new_query(token.split(':')[-1], join_type)
|
607
849
|
|
608
850
|
def add_where(self, token: str):
|
609
851
|
super().add_where(token.replace(':', '='))
|
610
852
|
|
611
853
|
def add_foreign_key(self, token: str, pk_field: str='') -> tuple:
|
612
|
-
self.new_query(token)
|
613
854
|
return super().add_foreign_key('{}_id', 'id')
|
614
855
|
|
615
856
|
# ----------------------------
|
@@ -729,12 +970,6 @@ class MongoParser(Parser):
|
|
729
970
|
# ----------------------------
|
730
971
|
|
731
972
|
|
732
|
-
class JoinType(Enum):
|
733
|
-
INNER = ''
|
734
|
-
LEFT = 'LEFT '
|
735
|
-
RIGHT = 'RIGHT '
|
736
|
-
FULL = 'FULL '
|
737
|
-
|
738
973
|
class Select(SQLObject):
|
739
974
|
join_type: JoinType = JoinType.INNER
|
740
975
|
REGEX = {}
|
@@ -784,16 +1019,7 @@ class Select(SQLObject):
|
|
784
1019
|
return query
|
785
1020
|
|
786
1021
|
def __str__(self) -> str:
|
787
|
-
|
788
|
-
LINE_BREAK = '\n' if self.break_lines else ' '
|
789
|
-
DEFAULT = lambda key: KEYWORD[key][1]
|
790
|
-
FMT_SEP = lambda key: KEYWORD[key][0].format(TABULATION)
|
791
|
-
select, _from, where, groupBy, orderBy, limit = [
|
792
|
-
DEFAULT(key) if not self.values.get(key) else "{}{}{}{}".format(
|
793
|
-
LINE_BREAK, key, TABULATION, FMT_SEP(key).join(self.values[key])
|
794
|
-
) for key in KEYWORD
|
795
|
-
]
|
796
|
-
return f'{select}{_from}{where}{groupBy}{orderBy}{limit}'.strip()
|
1022
|
+
return self.translate_to(QueryLanguage)
|
797
1023
|
|
798
1024
|
def __call__(self, **values):
|
799
1025
|
to_list = lambda x: x if isinstance(x, list) else [x]
|
@@ -836,6 +1062,8 @@ class Select(SQLObject):
|
|
836
1062
|
class_types += [GroupBy]
|
837
1063
|
FieldList(fields, class_types).add('', self)
|
838
1064
|
|
1065
|
+
def translate_to(self, language: QueryLanguage) -> str:
|
1066
|
+
return language(self).convert()
|
839
1067
|
|
840
1068
|
|
841
1069
|
class SelectIN(Select):
|
@@ -863,7 +1091,7 @@ class RuleSelectIN(Rule):
|
|
863
1091
|
@classmethod
|
864
1092
|
def apply(cls, target: Select):
|
865
1093
|
for i, condition in enumerate(target.values[WHERE]):
|
866
|
-
tokens = re.split('
|
1094
|
+
tokens = re.split(r'\s+or\s+|\s+OR\s+', re.sub('\n|\t|[()]', ' ', condition))
|
867
1095
|
if len(tokens) < 2:
|
868
1096
|
continue
|
869
1097
|
fields = [t.split('=')[0].split('.')[-1].lower().strip() for t in tokens]
|
@@ -909,7 +1137,7 @@ class RuleDateFuncReplace(Rule):
|
|
909
1137
|
"""
|
910
1138
|
SQL algorithm by Ralff Matias
|
911
1139
|
"""
|
912
|
-
REGEX = re.compile(r'(
|
1140
|
+
REGEX = re.compile(r'(YEAR[(]|year[(]|=|[)])')
|
913
1141
|
|
914
1142
|
@classmethod
|
915
1143
|
def apply(cls, target: Select):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: sql_blocks
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.9
|
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=CLkYCavcOlIieQkbersjZ30P_UvjFvrjXKxMdNURDVU,38486
|
3
|
+
sql_blocks-0.2.9.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
|
4
|
+
sql_blocks-0.2.9.dist-info/METADATA,sha256=XeK2YuLwhnYlQVq8My7GZfBJQ_gysd7pHGJTBFzwDEI,9675
|
5
|
+
sql_blocks-0.2.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
6
|
+
sql_blocks-0.2.9.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
|
7
|
+
sql_blocks-0.2.9.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
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,,
|
File without changes
|
File without changes
|
File without changes
|