Add a new json format

master
Salvo 'LtWorf' Tomaselli 2020-08-24 17:55:13 +07:00
parent 2e5d18f418
commit c4bc74d612
No known key found for this signature in database
GPG Key ID: B3A7CF0C801886CF
3 changed files with 60 additions and 25 deletions

@ -57,7 +57,7 @@ def load_relations():
print ("Loading relation %s with name %s..." % (i, relname))
rels[relname] = relation.Relation.load('%s%s' % (examples_path, i))
rels[relname] = relation.Relation.load_csv('%s%s' % (examples_path, i))
print('done')
@ -239,7 +239,7 @@ def run_test(testname):
o_result = None
try:
result_rel = relation.Relation.load('%s%s.result' % (tests_path, testname))
result_rel = relation.Relation.load_csv('%s%s.result' % (tests_path, testname))
query = readfile('%s%s.query' % (tests_path, testname)).strip()
o_query = optimizer.optimize_all(query, rels)

@ -90,8 +90,15 @@ class UserInterface:
def load(self, filename: str, name: str) -> None:
'''Loads a relation from file, and gives it a name to
be used in subsequent queries.'''
rel = Relation.load(filename)
be used in subsequent queries.
Files ending with .csv are loaded as csv, the others are
loaded as json.
'''
if filename.endswith('.csv'):
rel = Relation.load_csv(filename)
else:
rel = Relation.load(filename)
self.set_relation(name, rel)
def unload(self, name: str) -> None:
@ -161,8 +168,12 @@ class UserInterface:
if len(name) == 0:
return None
if (name.endswith(".csv")): # removes the extension
name = name[:-4]
# Removing the extension
try:
pos = name.rindex('.')
except ValueError:
return None
name = name[:pos]
if not is_valid_relation_name(name):
return None

@ -19,7 +19,6 @@
# This module provides a classes to represent relations and to perform
# relational operations on them.
import csv
from itertools import chain, repeat, product as iproduct
from collections import deque
from typing import FrozenSet, Iterable, List, Dict, Tuple
@ -62,21 +61,62 @@ class Relation:
content: FrozenSet[Tuple[CastValue, ...]]
@staticmethod
def load(filename: Union[str, Path]) -> 'Relation':
def load_csv(filename: Union[str, Path]) -> 'Relation':
'''
Load a relation object from a csv file.
The 1st row is the header and the other rows are the content.
Types will be inferred automatically
'''
import csv
with open(filename) as fp:
reader = csv.reader(fp) # Creating a csv reader
header = Header(next(reader)) # read 1st line
return Relation.create_from(header, reader)
@staticmethod
def load(filename: Union[str, Path]) -> 'Relation':
'''
Load a relation object from a json file.
'''
with open(filename) as fp:
from json import load as jload
from typedload import load
return load(jload(fp), Relation)
def save(self, filename: Union[Path, str]) -> None:
'''
Saves the relation in a file.
Will save using the json format
'''
with open(filename, 'w') as fp:
from json import dump as jdump
from typedload import dump
jdump(dump(self), fp)
def save_csv(self, filename: Union[Path, str]) -> None:
'''
Saves the relation in a file. Will save using the csv
format as defined in RFC4180.
'''
import csv
with open(filename, 'w') as fp:
writer = csv.writer(fp) # Creating csv writer
# It wants an iterable containing iterables
head = (self.header,)
writer.writerows(head)
# Writing content, already in the correct format
writer.writerows(self.content)
@staticmethod
def create_from(header: Iterable[str], content: Iterable[List[str]]) -> 'Relation':
'''
Iterator for the header, and iterator for the content.
This will infer types.
'''
header = Header(header)
r_content = []
@ -105,22 +145,6 @@ class Relation:
def __contains__(self, key):
return key in self.content
def save(self, filename: Union[Path, str]) -> None:
'''
Saves the relation in a file. Will save using the csv
format as defined in RFC4180.
'''
with open(filename, 'w') as fp:
writer = csv.writer(fp) # Creating csv writer
# It wants an iterable containing iterables
head = (self.header,)
writer.writerows(head)
# Writing content, already in the correct format
writer.writerows(self.content)
def _rearrange(self, other: 'Relation') -> 'Relation':
'''If two relations share the same attributes in a different order, this method
will use projection to make them have the same attributes' order.
@ -317,7 +341,7 @@ class Relation:
added = True
# If it didn't partecipate, adds it
if not added:
item = chain(i, repeat(None, len(noid))) #FIXME
item = chain(i, repeat(None, len(noid)))
content.append(tuple(item))
return Relation(header, frozenset(content))