Skip to content
Snippets Groups Projects
Commit 6d14e54d authored by Martin Nolte's avatar Martin Nolte
Browse files

completely remove database code

parent c71274cd
No related branches found
No related tags found
No related merge requests found
add_python_targets(generator
__init__
builder
database
generator
)
import json
import os.path
import re
from collections import namedtuple
def parse_dictionary(strings):
dictionary = dict()
for string in strings:
key_value = re.split('=', string)
if len(key_value) != 2:
raise Exception("Invalid key=value pair (" + string + ")")
dictionary[key_value[0]] = key_value[1]
return dictionary
# Selector
# --------
Selector = namedtuple("Selector", "grid parameters")
def selector(grid, **parameters):
return Selector(grid, parameters)
# DataBase
# --------
class DataBase:
class CompileError(Exception):
'''raise this when there's a problem compiling an extension module'''
def __init__(self, db, cpptype):
Exception.__init__(self,"DataBase::CompileError:")
self.db = db
self.cpptype = cpptype
def __str__(self):
return "Can not build extnesion module for the " + self.db +\
" with type '" + self.cpptype + "'"
class RangeError(Exception):
def __init__(self, grid):
Exception.__init__(self,"DataBase::RangeError:")
self.grid = grid
def __str__(self):
return "Cannot find definition for '" + self.grid + "'"
class MissingParameter(Exception):
def __init__(self, parameter):
Exception.__init__(self,"DataBase::MissingParameter:")
self.parameter = parameter
def __str__(self):
return "No value specified for parameter '" + self.parameter + "'"
class UnknownTranslation(Exception):
def __init__(self, parameter, value):
Exception.__init__(self,"DataBase::UnknownTranslation:")
self.parameter = parameter
self.value = value
def __str__(self):
return "Unable to translate value '" + self.value +\
"' for parameter '" + self.parameter + "'"
class FailedParameterCheck(Exception):
def __init__(self, checkStr, check):
Exception.__init__(self,"DataBase::FailedParameterCheck:")
self.checkStr = checkStr
self.check = check
def __str__(self):
return "Check '" + self.checkStr + "' failed ('" + self.check +\
"' evaluates to false)"
def __init__(self, *includes, **kwargs):
cppFile = kwargs.get("cppFile",False)
if not cppFile:
self.defs = dict()
for defs in includes:
self.defs.update(json.load(open(defs, 'r')))
else:
result = ""
with open(includes[0]) as infile:
copy = False
for line in infile:
if line.strip() == "BEGIN-DB":
copy = True
elif line.strip() == "END-DB":
copy = False
elif copy:
result = result + line
self.defs = {"Object":json.loads(result)}
def __len__(self):
return len(self.defs)
def iterkeys(self):
return iter(sorted(self.defs.keys()))
def __iter__(self):
return self.iterkeys()
def __repr__(self):
return json.dumps(self.defs, indent=2)
def __getitem__(self, key):
return self.defs[key]
def get_variables(self, grid):
variables = []
string = self.defs[grid]["type"]
while True:
match = re.search(r"\$\(([a-zA-Z][a-zA-Z0-9]*)\)", string)
if not match:
return variables
if match.group(1) not in variables:
variables += [match.group(1)]
string = string[match.end():]
def get_defaults(self, grid):
return parse_dictionary(self.defs[grid]["default"])\
if "default" in self.defs[grid] else dict()
def get_includes(self, selector):
if selector.grid not in self.defs:
raise DataBase.RangeError(selector.grid)
return self.defs[selector.grid].get("include",[])
def get_constructors(self, selector):
if selector.grid not in self.defs:
raise DataBase.RangeError(selector.grid)
return self.defs[selector.grid].get("constructors",[])
def get_methods(self, selector):
if selector.grid not in self.defs:
raise DataBase.RangeError(selector.grid)
return self.defs[selector.grid].get("methods",[])
def get_type(self, selector):
if selector.grid not in self.defs:
raise DataBase.RangeError(selector.grid)
defs = self.defs[selector.grid]
translations = dict()
if "translate" in defs:
for option in defs["translate"]:
translations[option] = parse_dictionary(defs["translate"][option])
return self.replace(defs["type"], selector.parameters,
self.get_defaults(selector.grid), translations)
def check_parameters(self, selector):
defs = self.defs[selector.grid]
if "checks" in defs:
for test in defs["checks"]:
self.check(test, selector.parameters, self.get_defaults(selector.grid))
def uses_extension(self, selector):
defs = self.defs[selector.grid]
if "extension" in defs:
if "extension" == "yes":
return True
else:
return False
# private methods
def replace(self, string, parameters, defaults, translations):
while True:
match = re.search(r"\$\(([a-zA-Z][a-zA-Z0-9]*)\)", string)
if not match:
break
option = match.group(1)
if option in parameters:
value = parameters[option]
elif option in defaults:
value = self.replace(defaults[option], parameters, defaults, translations)
parameters[option] = value
else:
raise DataBase.MissingParameter(option)
if option in translations:
if value in translations[option]:
value = translations[option][value]
else:
raise DataBase.UnknownTranslation(option, value)
string = string[:match.start()] + value + string[match.end():]
return string
def check(self, string, parameters, defaults):
before = string
while True:
match = re.search(r"\$\(([a-zA-Z][a-zA-Z0-9]*)\)", string)
if not match:
break
option = match.group(1)
if option in parameters:
value = parameters[option]
elif option in defaults:
value = defaults[option]
else:
raise DataBase.MissingParameter(option)
string = string[:match.start()] + value + string[match.end():]
if not eval(string):
raise DataBase.FailedParameterCheck(before, string)
......@@ -8,16 +8,7 @@
from __future__ import absolute_import, division, print_function, unicode_literals
import hashlib
import os
import re
from .builder import Builder
from . import database
from dune import __path__ as basePaths
dataBasePaths = [os.path.join(p, "../database") for p in basePaths]
builder = Builder()
......@@ -77,89 +68,3 @@ class SimpleGenerator(object):
setattr(module, "_includes", includes)
setattr(module, "_moduleName", moduleName)
return module
class Generator(SimpleGenerator):
""" Generator class:
The main class for on the fly generation of wrapper classes.
"""
def __init__(self, typeName, pathToRegisterMethod, namespace, pythonname=None, filename=None):
""" Constructor
Args:
typeName (string): identifier for the interface classes to be
generated (used for finding the right
dictionary files)
"""
SimpleGenerator.__init__(self, typeName, namespace, pythonname, filename)
if filename is None:
dbpaths = [os.path.join(p, typeName.lower()) for p in dataBasePaths]
dbfiles = []
for p in dbpaths:
if os.path.isdir(p):
dbfiles += [os.path.join(p,dbfile)
for dbfile in os.listdir(p)
if re.match(".*[.]db$", dbfile)]
self.dataBase = database.DataBase(*dbfiles,cppFile=False)
else:
self.dataBase = database.DataBase(filename,cppFile=True)
self.pathToRegisterMethod = pathToRegisterMethod
def getModule(self, myType, myTypeHash=None, **parameters):
""" generate and load the extension module for a given
implementation
Args:
myType (string): identifier for the dictionary entry to use
parameters (named arguments): values for free arguments
required for implementation's template arguments
Returns:
module: the name of the generated and imported extension module
"""
selector = database.selector(myType, **{i: str(parameters[i]) for i in parameters})
self.dataBase.check_parameters(selector)
myTypeName = self.modifyTypeName(self.dataBase.get_type(selector))
if not myTypeHash:
myTypeHash = hashlib.md5(myTypeName.encode('utf-8')).hexdigest()
moduleBase = self.typeName.lower()
moduleName = moduleBase + "_" + myTypeHash
includes = parameters[ "extra_includes" ] if "extra_includes" in parameters else []
includes += self.dataBase.get_includes(selector)
includes = self.modifyIncludes(includes)
if self.pathToRegisterMethod is not None:
includes += [self.pathToRegisterMethod + "/" + self.typeName.lower() + ".hh"]
# remove duplicate
# includes = list(set( includes ))
constructors = self.dataBase.get_constructors(selector)
methods = self.dataBase.get_methods(selector)
module = self.load(includes, myTypeName, moduleName, constructors, methods)
setattr(module, "_moduleBase", moduleBase)
setattr(module, "_selector", selector)
setattr(module, "_typeHash", myTypeHash)
return module
def modifyIncludes(self, includes):
return includes
def modifyTypeName(self, typeName):
return typeName
def getModule(filename, **parameters):
extra_includes=""
for k,v in parameters.items():
try:
module = v._module
parameters[k] = module._typeName
extra_includes += module._includes
except:
pass
with open(filename, 'r') as myfile:
fileHash = hashlib.md5(myfile.read().encode('utf-8')).hexdigest()
className = parameters.get("class","Object")
generator = Generator("Object", None, None, None, filename)
return generator.getModule("Object", myTypeHash=fileHash, extra_includes=extra_includes,**parameters).Object
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment