Browse Source

example of entity-class: user

refactor
Ulrich 2 years ago
parent
commit
099f244892
  1. 4
      basic/Testserver.py
  2. 4
      basic/compexec.py
  3. 1
      basic/constants.py
  4. 2
      basic/toolHandling.py
  5. 113
      make_workspace.py
  6. 143
      model/Entity.py
  7. 129
      model/entity.py
  8. 9
      model/user.csv
  9. 255
      model/user.py
  10. 23
      test/test_09git.py
  11. 2
      test/test_10job.py
  12. 131
      test/test_15user.py
  13. 30
      tools/config_tool.py
  14. 1
      tools/data_const.py
  15. 64
      tools/db_abstract.py
  16. 10
      tools/dbcsv_tool.py
  17. 20
      tools/dbmysql_tool.py
  18. 28
      tools/dbrel_tool.py
  19. 5
      tools/path_const.py

4
basic/Testserver.py

@ -10,7 +10,7 @@ import tools.file_tool
import tools.filecsv_fcts import tools.filecsv_fcts
import model.table import model.table
COMP_NAME = "testserver" COMP_NAME = B.ATTR_INST_TESTSERVER
COMP_TABLES = ["application", "ap_component", "ap_project", "ap_application", COMP_TABLES = ["application", "ap_component", "ap_project", "ap_application",
"environment", "en_component", "en_project"] "environment", "en_component", "en_project"]
@ -70,7 +70,7 @@ class Testserver(basic.component.Component):
print("model "+m) print("model "+m)
modelPath = os.path.join(path, m) modelPath = os.path.join(path, m)
modelDoc = fct.load_file(modelPath, D.CSV_SPECTYPE_DATA) modelDoc = fct.load_file(modelPath, D.CSV_SPECTYPE_DATA)
table = model.table.Table(job, project="", application="", component="Testserver", name=m[:-4]) table = model.table.Table(job, project="", application="", component=COMP_NAME, name=m[:-4])
sql = table.get_schema(tableName=m[:-4], tableObject=table) # [B.DATA_NODE_TABLES][m[:-4]] sql = table.get_schema(tableName=m[:-4], tableObject=table) # [B.DATA_NODE_TABLES][m[:-4]]
job.m.logInfo(sql) job.m.logInfo(sql)
tables[m[:-4]] = modelDoc tables[m[:-4]] = modelDoc

4
basic/compexec.py

@ -156,7 +156,7 @@ class Testexecuter():
def composeFileClauses(self, job, pattern): def composeFileClauses(self, job, pattern):
#job = basic.program.Job.getInstance() #job = basic.program.Job.getInstance()
out = {} out = {}
attr = tools.db_abstract.getDbAttributes(self, job, "null") attr = tools.db_abstract.getDbAttributes(job, self, job, "null")
while "{" in pattern: while "{" in pattern:
pre = pattern[0:pattern.index("{")] pre = pattern[0:pattern.index("{")]
pat = pattern[pattern.index("{"):pattern.index("}")] pat = pattern[pattern.index("{"):pattern.index("}")]
@ -198,7 +198,7 @@ class Testexecuter():
print("table "+table) print("table "+table)
sql_new = sql[0:sql.upper().index(" FROM ")+5] sql_new = sql[0:sql.upper().index(" FROM ")+5]
print("sql_new "+sql_new) print("sql_new "+sql_new)
attr = tools.db_abstract.getDbAttributes(self, table) attr = tools.db_abstract.getDbAttributes(job, self, table)
if attr[B.ATTR_DB_TABNAME] != "": if attr[B.ATTR_DB_TABNAME] != "":
table = attr[B.ATTR_DB_TABNAME] table = attr[B.ATTR_DB_TABNAME]
if attr[B.ATTR_DB_SCHEMA] != "": if attr[B.ATTR_DB_SCHEMA] != "":

1
basic/constants.py

@ -226,6 +226,7 @@ ATTR_INST_SGL = "single"
LIST_INST_ATTR = [ATTR_INST_CNT, ATTR_INST_SGL] LIST_INST_ATTR = [ATTR_INST_CNT, ATTR_INST_SGL]
SUBJECT_COMPS = "components" SUBJECT_COMPS = "components"
ATTR_INST_SUBCOMP = SUBJECT_COMPS ATTR_INST_SUBCOMP = SUBJECT_COMPS
ATTR_INST_TESTSERVER = "Testserver"
#SUBJECT_FCT = "function" # | | | | x | main-programs #SUBJECT_FCT = "function" # | | | | x | main-programs
""" """

2
basic/toolHandling.py

@ -74,7 +74,7 @@ def getDbTool(job, comp, dbtype=""):
filepath = os.path.join(job.conf[B.SUBJECT_PATH][B.ATTR_PATH_PROGRAM], "tools", toolname + ".py") filepath = os.path.join(job.conf[B.SUBJECT_PATH][B.ATTR_PATH_PROGRAM], "tools", toolname + ".py")
# comp.m.debug(verify, "toolname "+filepath) # comp.m.debug(verify, "toolname "+filepath)
if not os.path.exists(filepath): if not os.path.exists(filepath):
raise FileNotFoundError("file for tool " + toolname + " does not exist " + filepath) raise FileNotFoundError("dbi for tool " + toolname + " does not exist " + filepath)
cmodul = importlib.import_module("tools." + toolname) cmodul = importlib.import_module("tools." + toolname)
class_ = getattr(cmodul, "DbFcts") class_ = getattr(cmodul, "DbFcts")
c = class_() c = class_()

113
make_workspace.py

@ -1,113 +0,0 @@
# program to iinitialize the workspace
# pre: 1. program cloned
# 2. components are cloned, optional with path_const in config-folder
# post: 1. all folder are made with special name like components/const/path_const.py - otherwise with defaults
# 2. basic-configuration is created if it does not exist
# 3. necessary python-packages will be installed
# 4. git repos will be always updated
# -------------------------------------------------------------------------------------------------------------
"""
"""
import os
import basic.program
import tools.path_tool
import tools.file_tool
import basic.constants as B
# look if the path-constanst are specific defined.
home = os.getcwd()
if os.path.exists(os.path.join(home, "components", "config", "path_const.py")):
import components.config.path_const as P
else:
import tools.path_const as P
# import always the keyword.
import tools.path_const as Q
print("# ----------------------------------------------------------------------------------- ")
dirs = {}
dirs[Q.ATTR_PATH_HOME] = home
dirs[Q.ATTR_PATH_PROGRAM] = home
dirs[Q.ATTR_PATH_COMPONENTS] = os.path.join(home, "components")
pval = [P.ATTR_PATH_ARCHIV, P.ATTR_PATH_ENV, P.ATTR_PATH_DEBUG, P.ATTR_PATH_TEMP]
qkey = [Q.ATTR_PATH_ARCHIV, Q.ATTR_PATH_ENV, Q.ATTR_PATH_DEBUG, Q.ATTR_PATH_TEMP]
dirkey = [Q.ATTR_PATH_PROGRAM, Q.ATTR_PATH_COMPONENTS, Q.ATTR_PATH_HOME, Q.VAL_BASE_DATA] + qkey
home = tools.path_tool.getHome()
print("mkdirs in home " + home)
dirname = os.path.join(home, P.VAL_BASE_DATA)
dirs[Q.VAL_BASE_DATA] = dirname
if not os.path.exists(dirname):
os.makedirs(dirname, exist_ok=True)
print(" - "+dirname)
else:
print(" - " + dirname + " exists ")
dirname = os.path.join(home, P.VAL_CONFIG)
if not os.path.exists(dirname):
os.makedirs(dirname, exist_ok=True)
print(" - "+dirname)
else:
print(" - " + dirname + " exists ")
for i in range(0, len(pval)):
dirname = os.path.join(home, P.VAL_BASE_DATA, pval[i])
dirs[qkey[i]] = dirname
if not os.path.exists(dirname):
os.makedirs(dirname, exist_ok=True)
print(" - "+dirname)
else:
print(" - " + dirname + " exists ")
print("\n# ----------------------------------------------------------------------------------- ")
for format in ["yml", "json", "xml"]:
filename = os.path.join(home, Q.VAL_CONFIG, B.BASIS_FILE+"."+format)
if os.path.isfile(filename):
break
filename = ""
if len(filename) < 1:
filename = os.path.join(home, Q.VAL_CONFIG, B.BASIS_FILE+".yml")
text = "basic:\n"
text += " language: en\n"
text += " paths:\n"
for d in dirkey:
text += " "+d+": "+dirs[d]+"\n"
print(text)
print(filename)
with open(filename, 'w') as file:
file.write(text)
file.close()
print("create basis-config in "+filename)
print(text)
else:
print("basis-config exists "+filename)
print("\n# ----------------------------------------------------------------------------------- ")
print("please install requirements ")
# install requirements
# sudo apt install python3.10-venv
# python3 -m venv venv
# . venv/bin/activate
# pip install Flask
job = basic.program.Job("unit")
print("\n# ----------------------------------------------------------------------------------- ")
import tools.git_tool
for repo in ["program", "components", "testdata"]:
tools.git_tool.gitPull(job, repo)
print("\n# ----------------------------------------------------------------------------------- ")
if "db" in job.conf:
import basic.connection
entity = basic.connection.Connection(job)
entity.createSchema()
import model.testcase
entity = model.testcase.Testcase(job)
entity.createSchema()
import model.testsuite
entity = model.testsuite.Testsuite(job)
entity.createSchema()
import model.testplan
entity = model.testplan.Testplan(job)
entity.createSchema()
import basic.testexecution
entity = basic.testexecution.Testexecution(job)
entity.createSchema()

143
model/Entity.py

@ -1,143 +0,0 @@
import getpass
import os
import re
import basic.toolHandling
import tools.data_const as D
import basic.constants as B
import tools.date_tool
import tools.file_tool
class Entity:
def __int__(self, job):
self.job = job
self.table = ""
self.testserver = None
def get_schema(self):
"""
gets schema/ddl-informations in order to create the database
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def read_entity(self, job, name):
"""
reads the entity from the file-system
:param job:
:param name:
:return:
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def select_entity(self, job, name):
"""
reads the entity from the database
it should get the same result like read_entity
:param job:
:param name:
:return:
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def write_entity(self, job, name):
"""
writes the entity into the database
it similar to update_entity
:param job:
:param name:
:return:
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def update_entity(self, job, name):
"""
writes the entity into the database
it similar to update_entity
:param job:
:param name:
:return:
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def getDbAttr(self, job):
out = {}
for attr in [B.ATTR_DB_HOST, B.ATTR_DB_USER, B.ATTR_DB_DATABASE, B.ATTR_DB_PASSWD]:
out[attr] = job.conf[B.TOPIC_NODE_DB][attr]
return out
def getDdl(self, job, ddl):
out = {}
for t in ddl:
out[t] = {}
for f in ddl[t]:
out[t][f] = {}
for a in ddl[t][f]:
print("entity-23 "+f+", "+a+" "+str(ddl))
out[t][f][a] = ddl[t][f][a]
out[t][f][D.DDL_FIELD] = f
out[t][B.DATA_NODE_HEADER] = list(ddl[t].keys())
return out
def createSchema(self, testserver):
if B.TOPIC_NODE_DB in self.job.conf:
dbi = basic.toolHandling.getDbTool(self.job, testserver, self.job.conf[B.TOPIC_NODE_DB][B.ATTR_TYPE])
else:
return "No DB in job-config"
sql = self.get_schema()
print(sql)
for s in sql.split(";\n"):
if len(s) < 3: continue
try:
dbi.execStatement(s+";", self.job.conf[B.TOPIC_NODE_DB])
print("SQL executed: "+s)
except Exception as e:
raise Exception("Fehler bei createSchema "+s)
def getHistoryFields(self):
dbtype = self.job.conf[B.TOPIC_NODE_DB][B.ATTR_TYPE]
dbi = basic.toolHandling.getDbTool(self.job, None, dbtype)
sql = dbi.getSchemaAttribut("inscommit", D.TYPE_STR)+","
sql += dbi.getSchemaAttribut("insauthor", D.TYPE_STR)+","
sql += dbi.getSchemaAttribut("instime", D.TYPE_TIME)+","
sql += dbi.getSchemaAttribut("updcommit", D.TYPE_STR)+","
sql += dbi.getSchemaAttribut("updauthor", D.TYPE_STR)+","
sql += dbi.getSchemaAttribut("updtime", D.TYPE_TIME)+","
sql += dbi.getSchemaAttribut("actual", D.TYPE_INT)
return sql
def selectHistoryFields(self):
if B.TOPIC_NODE_DB in self.job.conf:
dbi = basic.toolHandling.getDbTool(self.job, self.testserver, self.job.conf[B.TOPIC_NODE_DB][B.ATTR_TYPE])
else:
return "No DB in job-config"
dbi.selectRows
def getHistoryIndex(self, table):
dbtype = self.job.conf[B.TOPIC_NODE_DB][B.ATTR_TYPE]
dbi = basic.toolHandling.getDbTool(self.job, None, dbtype)
sql = dbi.getSchemaIndex(table, "actual") + "\n"
return sql
def read_spec(job, testentity, testgran, specpath):
if not os.path.isfile(specpath):
return
text = tools.file_tool.read_file_text(job, specpath, job.m)
if re.match(r".*?depricated;[jJyY]", text):
return None
spec = {}
regex = re.compile(r".*\nhead:(.*?);(.+)")
for res in regex.finditer(text):
#res = re.search(r".*head:(.*?);(.+)\n", text)
key = res.group(1)
if key == B.SUBJECT_DESCRIPTION:
spec[B.SUBJECT_DESCRIPTION] = res.group(2).replace(";", "")
elif key in [B.SUBJECT_APPS, B.PAR_APP]:
apps = res.group(2).replace(";", ",").split(",")
spec[B.SUBJECT_APPS] = apps
else:
val = res.group(2).replace(";", "")
spec[key] = val
return spec

129
model/entity.py

@ -2,6 +2,7 @@ import getpass
import os import os
import re import re
import basic.toolHandling import basic.toolHandling
import model.entity
import tools.data_const as D import tools.data_const as D
import basic.constants as B import basic.constants as B
import tools.date_tool import tools.date_tool
@ -25,6 +26,10 @@ SYNC_HEAD_GIT2DB = "head-git-db"
SYNC_COPY_FILE2DB = "copy-file-db" SYNC_COPY_FILE2DB = "copy-file-db"
SYNC_ONLY_GIT = "only-git" SYNC_ONLY_GIT = "only-git"
SYNC_ONLY_DB = "only-db" SYNC_ONLY_DB = "only-db"
STORAGE_DB = B.TOPIC_NODE_DB
STORAGE_FILE = B.TOPIC_NODE_FILE
LIST_ENTITY_SYNC = [SYNC_ONLY_GIT, SYNC_FULL_GIT2DB, SYNC_HEAD_GIT2DB, SYNC_COPY_FILE2DB, SYNC_ONLY_DB] LIST_ENTITY_SYNC = [SYNC_ONLY_GIT, SYNC_FULL_GIT2DB, SYNC_HEAD_GIT2DB, SYNC_COPY_FILE2DB, SYNC_ONLY_DB]
@ -51,17 +56,96 @@ class Entity:
self.table = "" self.table = ""
self.testserver = None self.testserver = None
def get_unique_names(self, job, storage="", project="", application="", gran="", args={}):
"""
gets the entity-names from the defined storage - the field name must be an unique identifier
:param job:
:param opt. storage: values db / files - default files
:param opt. project: select-criteria if used and defined
:param opt. application: select-criteria if used and defined
:param opt. gran: granularity values testcase / testsuite / testplan
:param opt. args additional args
:return: list of entity-names
"""
entityNames = []
if storage == STORAGE_DB:
entityNames = self.select_unique_names(job, project, application, gran, args)
elif storage == STORAGE_FILE:
entityNames = self.read_unique_names(job, project, application, gran, args)
else:
entityNames = self.read_unique_names(job, project, application, gran, args)
return entityNames
def get_entities(self, job, storage="", project="", application="", gran="", args={}):
"""
gets the entity-names from the defined storage
:param job:
:param opt. storage: values db / files - default files
:param opt. project: select-criteria if used and defined
:param opt. application: select-criteria if used and defined
:param opt. gran: granularity values testcase / testsuite / testplan
:param opt. args additional args
:return: list of entity-names
"""
entities = []
entityNames = self.get_unique_names(job, storage=storage, project=project, application=application,
gran=gran, args=args)
for k in entityNames:
if storage == STORAGE_DB:
entity = self.select_entity(job, k)
elif storage == STORAGE_FILE:
entity = self.read_entity(job, k)
else:
entity = self.read_entity(job, k)
entities.append(entity)
return entities
def read_unique_names(self, job, project, application, gran, args):
"""
reads the entity-names from file-storage
:param job:
:param opt. project: select-criteria if used and defined
:param opt. application: select-criteria if used and defined
:param opt. gran: granularity values testcase / testsuite / testplan
:param opt. args additional args
:return: list of entity-names
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def select_unique_names(self, job, project, application, gran, args):
"""
reads the entity-names from file-storage
:param job:
:param opt. project: select-criteria if used and defined
:param opt. application: select-criteria if used and defined
:param opt. gran: granularity values testcase / testsuite / testplan
:param opt. args additional args
:return: list of entity-names
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def setDbAttributes(self, job, tables):
"""
set the db-attributes like connection and ddl
:param job:
:param tables: list of table-names
:return:
"""
setattr(self, "m", job.m)
config = {}
config[B.SUBJECT_CONN] = job.conf[B.TOPIC_NODE_DB]
config[B.DATA_NODE_DDL] = {}
for t in tables:
ddl = tools.db_abstract.get_ddl(job, B.ATTR_INST_TESTSERVER, t)
config[B.DATA_NODE_DDL][t] = ddl
setattr(self, "conf", config)
def getEntity(self, job, name): def getEntity(self, job, name):
if B.TOPIC_NODE_DB in job.conf: if B.TOPIC_NODE_DB in job.conf:
self.select_entity(job, name) self.select_entity(job, name)
#self.read_entity(job, name) #self.read_entity(job, name)
else: else:
self.read_entity(job, name) self.read_entity(job, name)
def get_schema(self, tableName="", tableObject=None):
"""
gets schema/ddl-informations in order to create the database
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def read_entity(self, job, name): def read_entity(self, job, name):
""" """
@ -84,7 +168,17 @@ class Entity:
def write_entity(self, job, name): def write_entity(self, job, name):
""" """
writes the entity into the database writes the entity into the file-system
it similar to update_entity
:param job:
:param name:
:return:
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def insert_entity(self, job, name):
"""
inserts the entity into the database
it similar to update_entity it similar to update_entity
:param job: :param job:
:param name: :param name:
@ -112,7 +206,26 @@ class Entity:
""" """
raise Exception(B.EXCEPT_NOT_IMPLEMENT) raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def delete_entity(self, job, name): def removeEntity(self, job, name, storagepath, ext):
"""
removes the entity from the file-system
it similar to delete_entity
:param job:
:param name: single substring or list of name or dict of names with the keys as
:return:
"""
nameList = []
if isinstance(name, dict):
nameList = name.keys()
elif isinstance(name, list):
nameList = name
else:
nameList.append(name)
for name in nameList:
pathname = os.path.join(storagepath, name + "." + ext)
os.remove(pathname)
def delete_entity(self, job, name, table):
""" """
deletes the entity into the database deletes the entity into the database
it similar to update_entity it similar to update_entity
@ -151,7 +264,7 @@ class Entity:
for s in sql.split(";\n"): for s in sql.split(";\n"):
if len(s) < 3: continue if len(s) < 3: continue
try: try:
dbi.execStatement(s+";", self.job.conf[B.TOPIC_NODE_DB]) # dbi.execStatement(s+";", self.job.conf[B.TOPIC_NODE_DB])
print("SQL executed: "+s) print("SQL executed: "+s)
except Exception as e: except Exception as e:
raise Exception("Fehler bei createSchema "+s) raise Exception("Fehler bei createSchema "+s)

9
model/user.csv

@ -0,0 +1,9 @@
table:user;_field;type;format;index;generic;aggregat;key;acceptance;alias;description
;id;pk;autoint;N;;;T:1;;;
;username;str;vchar(256);N;;;F:1;;;
;name;str;vchar(256);N;;;;;;
;famname;str;vchar(256);N;;;;;;
;email;string;vchar(256);N;;;;;;
;password;string;vchar(256);N;;;;;;
;project;string;vchar(256);N;;;;;;
;role;string;vchar(256);N;;;;;;
1 table:user _field type format index generic aggregat key acceptance alias description
2 id pk autoint N T:1
3 username str vchar(256) N F:1
4 name str vchar(256) N
5 famname str vchar(256) N
6 email string vchar(256) N
7 password string vchar(256) N
8 project string vchar(256) N
9 role string vchar(256) N

255
model/user.py

@ -0,0 +1,255 @@
# ---------------------------------------------------------------------------------------------------------
# Author : Ulrich Carmesin
# Source : gitea.ucarmesin.de
# ---------------------------------------------------------------------------------------------------------
import os
import basic.toolHandling
import basic.constants as B
import model.entity
import tools.path_const as P
import tools.data_const as D
import tools.config_tool
import tools.file_tool
import tools.db_abstract
import tools.git_tool
TABLE_NAME = "user"
""" system-name for this entity """
FIELD_ID = "id"
FIELD_USERNAME = "username"
FIELD_NAME = "name"
FIELD_FAMNAME = "famname"
FIELD_EMAIL = "email"
FIELD_PASSWORD = "password"
FIELD_PROJECT = "project"
FIELD_ROLE = "role"
LIST_FIELDS = [FIELD_ID, FIELD_ROLE, FIELD_PROJECT, FIELD_PASSWORD, FIELD_EMAIL, FIELD_FAMNAME, FIELD_NAME, FIELD_USERNAME]
""" list of object-attributes """
FILE_EXTENSION = D.DFILE_TYPE_YML
UNIQUE_FIELDS = [FIELD_USERNAME]
""" unique business field as human identifer """
IDENTIFYER_FIELDS = [FIELD_ID]
""" unique technical field as technical identifer """
class User(model.entity.Entity):
id = 0
username = ""
name = ""
famname = ""
email = ""
password = ""
project = ""
role = ""
def __int__(self, job, name=""):
self.job = job
if len(name) > 1:
self.getEntity(job, name)
def read_unique_names(self, job, project, application, gran, args):
"""
reads the entity-names from file-storage
:param job:
:param opt. project: select-criteria if used and defined
:param opt. application: select-criteria if used and defined
:param opt. gran: granularity values testcase / testsuite / testplan
:param opt. args additional args
:return: list of entity-names
"""
outList = []
path = os.path.join(job.conf[B.SUBJECT_PATH][B.ATTR_PATH_HOME], P.VAL_CONFIG, "user")
for k in os.listdir(path):
filename = tools.config_tool.get_plain_filename(job, k)
if "default" == filename:
continue
outList.append(filename)
return outList
def select_unique_names(self, job, project, application, gran, args):
"""
reads the entity-names from file-storage
:param job:
:param opt. project: select-criteria if used and defined
:param opt. application: select-criteria if used and defined
:param opt. gran: granularity values testcase / testsuite / testplan
:param opt. args additional args
:return: list of entity-names
"""
outList = []
self.setDbAttributes(job, [TABLE_NAME])
dbi = basic.toolHandling.getDbTool(job, self, job.conf[B.TOPIC_NODE_DB]["type"])
data = dbi.selectRows(TABLE_NAME, job)
checkList = {}
for row in data[B.DATA_NODE_DATA]:
key = ""
for f in UNIQUE_FIELDS:
key += "_" + row[f]
if key in checkList:
continue
else:
checkList[key] = key
fields = []
for f in UNIQUE_FIELDS:
fields.append(row[f])
outList.append(fields)
return outList
def read_entity(self, job, name):
"""
reads the entity from the file-system
:param job:
:param name:
:return:
"""
print("name "+name)
config = model.user.User.getUserConfig(job, tools.config_tool.get_plain_filename(job, name))
for k in LIST_FIELDS:
if k not in config:
continue
setattr(self, k, config[k])
return self
def select_entity(self, job, name, row={}):
"""
reads the entity from the database
it should get the same result like read_entity
:param job:
:param name: unique field as string, unique fields as list
the unique-fields are defined in the class
:return: itself with filled object-attributes
"""
if row is None or len(row) == 0:
self.setDbAttributes(job, [TABLE_NAME])
dbi = basic.toolHandling.getDbTool(job, self, job.conf[B.TOPIC_NODE_DB]["type"])
if type(name) is list:
names = name
elif type(name) is str:
names = [name]
condition = "where "
for v in names:
condition += " and " + ""
data = dbi.selectRows(TABLE_NAME, job, "where username = \'" + names[0] + "\'")
if len(data[B.DATA_NODE_DATA]) > 1:
raise Exception("single selection with more than one result: "+names[0])
elif len(data[B.DATA_NODE_DATA]) == 1:
row = data[B.DATA_NODE_DATA][0]
else:
raise Exception("no result for: "+names[0])
for k in LIST_FIELDS:
if k not in row:
continue
setattr(self, k, row[k])
return self
def write_entity(self, job, name):
"""
writes the entity into the file-system
it similar to update_entity
:param job:
:param name:
:return:
"""
config = {}
config[model.user.TABLE_NAME] = {}
pathname = os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_HOME], P.VAL_CONFIG,
P.VAL_USER, name + ".yml")
for k in LIST_FIELDS:
if getattr(self, k, "") == "" \
or k == FIELD_ID:
continue
config[model.user.TABLE_NAME][k] = getattr(self, k, "")
tools.file_tool.write_file_dict(job.m, job, pathname, config)
return self
def insert_entity(self, job, name, table="", rows={}):
"""
inserts the entity into the database
it similar to update_entity
:param job:
:param name:
:return:
"""
self.setDbAttributes(job, [TABLE_NAME])
dbi = basic.toolHandling.getDbTool(job, self, job.conf[B.TOPIC_NODE_DB]["type"])
condition = "where"
for f in UNIQUE_FIELDS:
# TODO other db-formats than string has to be implemented
condition += " and " + f + " = \'" + getattr(self, f, "") + "\'"
condition = condition.replace("where and", "where ")
data = dbi.selectRows(TABLE_NAME, job, condition)
if len(data[B.DATA_NODE_DATA]) > 0:
print("update statt insert")
return
if rows is None or len(rows) == 0:
insheader = dbi.getInsertFields(self.conf[B.DATA_NODE_DDL][table])
rows = []
row = {}
for f in insheader:
row[f] = getattr(self, f)
rows.append(row)
dbi.insertRows(job, table, rows)
def update_entity(self, job, name):
"""
writes the entity into the database
it similar to update_entity
:param job:
:param name:
:return:
"""
raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def remove_entity(self, job, name):
"""
removes the entity from the file-system
it similar to delete_entity
:param job:
:param name: single substring or list of name or dict of names with the keys as
:return:
"""
self.removeEntity(job, name, os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_HOME], P.VAL_CONFIG, P.VAL_USER), "yml")
def delete_entity(self, job, name, table):
"""
deletes the entity into the database
it similar to update_entity
:param job:
:param name:
:return:
"""
self.setDbAttributes(job, [TABLE_NAME])
dbi = basic.toolHandling.getDbTool(job, self, job.conf[B.TOPIC_NODE_DB]["type"])
condition = "where"
for f in IDENTIFYER_FIELDS:
# TODO other db-formats than string has to be implemented
val = dbi.getDbValue(self.conf[B.DATA_NODE_DDL][table][f], getattr(self, f, ""))
condition += " and " + f + " = " + val + ""
condition = condition.replace("where and", "where ")
dbi.deleteRows(job, table, condition)
@staticmethod
def getUserConfig(job, name):
"""
reads the entity from the database
it should get the same result like read_entity
:param job:
:param name:
:return:
"""
config = tools.config_tool.getConfig(job, P.KEY_USER, name)
if config is not None:
return config
if name == model.user.User.getCurrentUser(job):
config = tools.config_tool.getConfig(job, P.KEY_USER, "default")
if "user" in config:
config = config["user"]
if config is not None:
config["username"] = name
return config
raise Exception("keine Config zu "+name)
@staticmethod
def getCurrentUser(job):
return os.environ.get("USERNAME")

23
test/test_09git.py

@ -1,14 +1,11 @@
import unittest import unittest
import os
import inspect import inspect
import utils.path_tool import tools.path_tool
import basic.message
import basic.program
import basic.constants as B import basic.constants as B
import test.constants import test.constants
import test.testtools import test.testtools
import utils.path_const as P import tools.path_const as P
import utils.git_tool import tools.git_tool
HOME_PATH = test.constants.HOME_PATH HOME_PATH = test.constants.HOME_PATH
OS_SYSTEM = test.constants.OS_SYSTEM OS_SYSTEM = test.constants.OS_SYSTEM
@ -28,7 +25,7 @@ class MyTestCase(unittest.TestCase):
if actfunction not in TEST_FUNCTIONS: if actfunction not in TEST_FUNCTIONS:
return return
job = test.testtools.getJob() job = test.testtools.getJob()
result = utils.git_tool.runGit(job, B.ATTR_PATH_PROGRAM, "git status") result = tools.git_tool.runGit(job, B.ATTR_PATH_PROGRAM, "git status")
MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest)
def test_02status(self): def test_02status(self):
@ -38,7 +35,7 @@ class MyTestCase(unittest.TestCase):
if actfunction not in TEST_FUNCTIONS: if actfunction not in TEST_FUNCTIONS:
return return
job = test.testtools.getJob() job = test.testtools.getJob()
result = utils.git_tool.gitStatus(job, B.ATTR_PATH_PROGRAM) result = tools.git_tool.gitStatus(job, B.ATTR_PATH_PROGRAM)
MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest)
def test_03log(self): def test_03log(self):
@ -48,13 +45,13 @@ class MyTestCase(unittest.TestCase):
if actfunction not in TEST_FUNCTIONS: if actfunction not in TEST_FUNCTIONS:
return return
job = test.testtools.getJob() job = test.testtools.getJob()
result = utils.git_tool.gitLog(job, B.ATTR_PATH_COMPS) result = tools.git_tool.gitLog(job, B.ATTR_PATH_COMPS)
self.assertGreaterEqual(10, len(result)) self.assertGreaterEqual(10, len(result))
result = utils.git_tool.gitLog(job, B.ATTR_PATH_COMPS, cnt=1) result = tools.git_tool.gitLog(job, B.ATTR_PATH_COMPS, cnt=1)
self.assertEqual(1, len(result)) self.assertEqual(1, len(result))
apppath = utils.config_tool.getConfigPath(job, P.KEY_BASIC, B.SUBJECT_APPS, "") apppath = tools.config_tool.select_config_path(job, P.KEY_BASIC, B.SUBJECT_APPS, "")
repopath = apppath[len(job.conf.confs[B.SUBJECT_PATH][B.ATTR_PATH_COMPS])+1:] repopath = apppath[len(job.conf[B.SUBJECT_PATH][B.ATTR_PATH_COMPS])+1:]
result = utils.git_tool.gitLog(job, B.ATTR_PATH_COMPS, repopath, 1) result = tools.git_tool.gitLog(job, B.ATTR_PATH_COMPS, repopath, 1)
self.assertEqual(1, len(result)) self.assertEqual(1, len(result))
MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest) MyTestCase.mymsg += "\n----- "+actfunction+" : "+str(cnttest)

2
test/test_10job.py

@ -16,7 +16,7 @@ import tools.file_tool
HOME_PATH = test.constants.HOME_PATH HOME_PATH = test.constants.HOME_PATH
PYTHON_CMD = "python" PYTHON_CMD = "python"
TEST_FUNCTIONS = ["test_00init", "test_30startActJob"] TEST_FUNCTIONS = ["test_00init", "test_30startActJob"]
TEST_FUNCTIONS = ["test_30startActJob"] TEST_FUNCTIONS = ["test_00init"]
PROGRAM_NAME = "clean_workspace" PROGRAM_NAME = "clean_workspace"

131
test/test_15user.py

@ -0,0 +1,131 @@
import unittest
import os
import inspect
import shutil
import tools.path_tool
import basic.program
import test.testtools
import basic.constants as B
import test.constants as T
import tools.file_tool
import model.user
import model.entity
HOME_PATH = test.constants.HOME_PATH
PYTHON_CMD = "python"
TEST_FUNCTIONS = ["test_10getEntityNames", "test_11getEntities", "test_12getEntity",
"test_13writeEntity", "test_14insertEntity"]
TEST_FUNCTIONS = ["test_14insertEntity"]
PROGRAM_NAME = "clean_workspace"
class MyTestCase(unittest.TestCase):
mymsg = "--------------------------------------------------------------"
def test_10getEntityNames(self):
global mymsg
global jobObject
actfunction = str(inspect.currentframe().f_code.co_name)
cnttest = 0
if actfunction not in TEST_FUNCTIONS:
return
job = test.testtools.getJob()
user = model.user.User()
entityNames = []
entityNames = user.read_unique_names(job, "", "", "", {})
self.assertEquals(type(entityNames), list)
entityNames = user.select_unique_names(job, "", "", "", {})
self.assertEquals(type(entityNames), list)
def test_11getEntities(self):
global mymsg
global jobObject
actfunction = str(inspect.currentframe().f_code.co_name)
cnttest = 0
if actfunction not in TEST_FUNCTIONS:
return
job = test.testtools.getJob()
user = model.user.User()
entityNames = []
entityNames = user.get_entities(job, storage=model.entity.STORAGE_FILE)
self.assertEqual(type(entityNames), list)
entityNames = user.get_entities(job, storage=model.entity.STORAGE_DB)
self.assertEqual(type(entityNames), list)
def test_12getEntity(self):
global mymsg
global jobObject
actfunction = str(inspect.currentframe().f_code.co_name)
cnttest = 0
if actfunction not in TEST_FUNCTIONS:
return
job = test.testtools.getJob()
user = model.user.User()
name = "ulrich"
actUser = user.read_entity(job, name)
self.assertEqual(getattr(actUser, model.user.FIELD_USERNAME), name)
self.assertRaises(Exception, user.read_entity, job, "xyzxyz")
#
actUser = user.select_entity(job, name)
self.assertEqual(getattr(actUser, model.user.FIELD_USERNAME), name)
self.assertRaises(Exception, user.select_entity, job, ["xyzxyz"])
def test_13writeEntity(self):
global mymsg
global jobObject
actfunction = str(inspect.currentframe().f_code.co_name)
cnttest = 0
if actfunction not in TEST_FUNCTIONS:
return
job = test.testtools.getJob()
username = "hans_xyz"
user = model.user.User()
entityNames = user.get_unique_names(job, storage=model.entity.STORAGE_FILE)
self.assertNotIn(username, entityNames)
user.username = username
user.name = "Hans"
user.famname = "im Glueck"
user.project = "TESTPROJ"
user.write_entity(job, username)
entityNames = user.get_unique_names(job, storage=model.entity.STORAGE_FILE)
self.assertIn(username, entityNames)
actUser = user.read_entity(job, username)
self.assertEquals(getattr(actUser, model.user.FIELD_USERNAME), username)
actUser.remove_entity(job, username)
entityNames = user.get_unique_names(job, storage=model.entity.STORAGE_FILE)
self.assertNotIn(username, entityNames)
def test_14insertEntity(self):
global mymsg
global jobObject
actfunction = str(inspect.currentframe().f_code.co_name)
cnttest = 0
if actfunction not in TEST_FUNCTIONS:
return
job = test.testtools.getJob()
username = "hans_xyz"
user = model.user.User()
entityNames = collectInnerList(user.get_unique_names(job, storage=model.entity.STORAGE_DB))
#self.assertNotIn(username, entityNames)
user.username = username
user.name = "Hans"
user.famname = "im Glueck"
user.project = "TESTPROJ"
#user.insert_entity(job, username, table="user")
entityNames = collectInnerList(user.get_unique_names(job, storage=model.entity.STORAGE_DB))
self.assertIn(username, entityNames)
actUser = user.select_entity(job, username)
self.assertEquals(getattr(actUser, model.user.FIELD_USERNAME), username)
actUser.delete_entity(job, username, "user")
entityNames = collectInnerList(user.get_unique_names(job, storage=model.entity.STORAGE_DB))
self.assertNotIn(username, entityNames)
def collectInnerList(inList):
outList = []
for r in inList:
outList += r
return outList
if __name__ == '__main__':
unittest.main()

30
tools/config_tool.py

@ -84,6 +84,8 @@ def select_config_path(job, modul, name, subname=""):
return getTestPath(job, name, D.DFILE_TESTSUITE_NAME) return getTestPath(job, name, D.DFILE_TESTSUITE_NAME)
elif modul == P.KEY_CATALOG: elif modul == P.KEY_CATALOG:
return getCatalogPath(job, name) return getCatalogPath(job, name)
elif modul == P.KEY_USER:
return getUserPath(job, name)
else: else:
pathname = tools.path_tool.compose_path(job, P.P_TCPARFILE) pathname = tools.path_tool.compose_path(job, P.P_TCPARFILE)
if verify: job.debug(verify, "7 " + pathname) if verify: job.debug(verify, "7 " + pathname)
@ -153,11 +155,11 @@ def getCompPath(job, name, subname, filename):
configpath = getExistingPath(job, pathnames) configpath = getExistingPath(job, pathnames)
if configpath is not None: if configpath is not None:
return configpath return configpath
if name == "Testserver": if name == B.ATTR_INST_TESTSERVER:
print(name) print(name)
for format in CONFIG_FORMAT: for format in CONFIG_FORMAT:
pathname = os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_PROGRAM], pathname = os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_PROGRAM],
"model", subname + "." + format) P.ATTR_PATH_MODEL, subname + "." + format)
print(pathname) print(pathname)
if os.path.exists(pathname): if os.path.exists(pathname):
return pathname return pathname
@ -215,6 +217,28 @@ def getCatalogPath(job, name):
return path return path
raise Exception(P.EXP_CONFIG_MISSING, name) raise Exception(P.EXP_CONFIG_MISSING, name)
def getUserPath(job, name):
for ext in CONFIG_FORMAT:
pathname = os.path.join(job.conf[B.SUBJECT_PATH][P.ATTR_PATH_HOME], P.VAL_CONFIG,
P.VAL_USER, name + "." + ext)
if os.path.exists(pathname):
return pathname
return None
def get_plain_filename(job, path):
"""
the function extracts the plain filename without directory-name and extension
:param job:
:param path:
:return:
"""
names = list(os.path.split(path))
filename = names.pop()
for ext in CONFIG_FORMAT:
if filename[-len(ext):] == ext:
filename = filename[:-len(ext)-1]
return filename
return filename
def getConfValue(attribute, comp): def getConfValue(attribute, comp):
if attribute == B.ATTR_CONN_DBTYPE: if attribute == B.ATTR_CONN_DBTYPE:
@ -262,6 +286,8 @@ def getConfig(job, modul, name, subname=""):
if hasattr(job, "m"): msg = job.m if hasattr(job, "m"): msg = job.m
pathname = select_config_path(job, modul, name, subname) pathname = select_config_path(job, modul, name, subname)
confs = {} confs = {}
if pathname is None:
return None
job.debug(verify, "getConfig " + pathname) job.debug(verify, "getConfig " + pathname)
if len(pathname) < 1: if len(pathname) < 1:
return confs return confs

1
tools/data_const.py

@ -16,6 +16,7 @@ TYPE_DOUBLE = "double"
TYPE_DATE = "date" TYPE_DATE = "date"
TYPE_TIME = "time" TYPE_TIME = "time"
TYPE_PK = "pk" TYPE_PK = "pk"
TYPE_AUTOINT = "autoint"
# fields in DDL # fields in DDL
# _field;comment;format;acceptance;generate;nullable # _field;comment;format;acceptance;generate;nullable

64
tools/db_abstract.py

@ -49,9 +49,40 @@ import tools.data_const as D
import tools.date_tool import tools.date_tool
import os import os
def get_ddl(job, compName, table):
"""
this function read the ddl from the right config
:param job:
:param compName:
:param table:
:return: ddl in correct format
"""
out = {}
conf = tools.config_tool.getConfig(job, D.DDL_FILENAME, compName, table)
if B.DATA_NODE_TABLES in conf and table in conf[B.DATA_NODE_TABLES]:
ddl = conf[B.DATA_NODE_TABLES][table]
elif table in conf:
ddl = conf[table]
else:
ddl = conf
# workaround because a csv-file is loaded in wrong format
if B.DATA_NODE_DATA in ddl:
header = []
for e in ddl[B.DATA_NODE_DATA]:
k = e[D.DDL_FIELD]
e.pop(D.DDL_FIELD)
header.append(k)
out[k] = e
for k in D.LIST_DATA_ATTR:
if k not in ddl:
continue
out[k] = ddl[k]
out[B.DATA_NODE_HEADER] = header
else:
out = ddl
return out
def getDbAttributes(job, comp, table):
def getDbAttributes(comp, table):
""" """
this function collects all relevant db-attributes from any location where it can be set. this function collects all relevant db-attributes from any location where it can be set.
The location could be The location could be
@ -69,6 +100,13 @@ def getDbAttributes(comp, table):
B.ATTR_DB_CONN_JAR: D.DEFAULT_DB_CONN_JAR B.ATTR_DB_CONN_JAR: D.DEFAULT_DB_CONN_JAR
} }
for attr in out.keys(): for attr in out.keys():
if comp is None or not hasattr(comp, "conf"):
print("dbi ohne comp")
if B.TOPIC_NODE_DB not in job.conf:
raise Exception("Keine DB-Attribute in job")
if (attr in job.conf[B.TOPIC_NODE_DB]):
out[attr] = job.conf[B.TOPIC_NODE_DB][attr]
else:
if (B.SUBJECT_ARTS in comp.conf and table in comp.conf[B.SUBJECT_ARTS][B.TOPIC_NODE_DB]) \ if (B.SUBJECT_ARTS in comp.conf and table in comp.conf[B.SUBJECT_ARTS][B.TOPIC_NODE_DB]) \
and (attr in comp.conf[B.SUBJECT_ARTS][B.TOPIC_NODE_DB][table]): and (attr in comp.conf[B.SUBJECT_ARTS][B.TOPIC_NODE_DB][table]):
out[attr] = comp.conf[B.SUBJECT_ARTS][B.TOPIC_NODE_DB][table][attr] out[attr] = comp.conf[B.SUBJECT_ARTS][B.TOPIC_NODE_DB][table][attr]
@ -157,14 +195,14 @@ def parseSQLwhere(condition, ddl=None):
return "WHERE "+dbwhere.strip() return "WHERE "+dbwhere.strip()
def getSqlTable(comp, table): def getSqlTable(job, comp, table):
""" """
the function gets the technical tablename inclusive necessary schema information the function gets the technical tablename inclusive necessary schema information
:param comp: :param comp:
:param table: :param table:
:return: :return:
""" """
attr = getDbAttributes(comp, table) attr = getDbAttributes(job, comp, table)
if attr[B.ATTR_DB_TABNAME] != "": if attr[B.ATTR_DB_TABNAME] != "":
sqltable = attr[B.ATTR_DB_TABNAME] sqltable = attr[B.ATTR_DB_TABNAME]
else: else:
@ -240,7 +278,7 @@ def formatDbVal(msg, val, dtyp):
if not isinstance(val, str): if not isinstance(val, str):
msg.logError("field must be " + dtyp + ", " + str(val)) msg.logError("field must be " + dtyp + ", " + str(val))
return tools.date_tool.getFormatDatetupel(tools.date_tool.parseDate(val), tools.date_tool.F_DB_TIME) return tools.date_tool.getFormatDatetupel(tools.date_tool.parseDate(val), tools.date_tool.F_DB_TIME)
if dtyp == D.TYPE_INT: if dtyp in [D.TYPE_INT, D.TYPE_PK]:
if not (isinstance(val, int) or re.match(r"^\d+$", val)): if not (isinstance(val, int) or re.match(r"^\d+$", val)):
msg.logError("field must be " + dtyp + ", " + str(val)) msg.logError("field must be " + dtyp + ", " + str(val))
return 0 return 0
@ -282,14 +320,14 @@ class DbFcts():
self.job = job self.job = job
self.comp = comp self.comp = comp
def getDbAttributes(self, table): def getDbAttributes(self, job, table):
""" """
this function collects all relevant db-attributes from any location where it can be set. this function collects all relevant db-attributes from any location where it can be set.
The location could be The location could be
* comp.artifact.db.[table].attr * comp.artifact.db.[table].attr
* comp.artifact.[db].[table].attr * comp.artifact.[db].[table].attr
""" """
return getDbAttributes(self.comp, table) return getDbAttributes(job, self.comp, table)
def selectTables(self, subdir, job): def selectTables(self, subdir, job):
@ -321,9 +359,9 @@ class DbFcts():
self.loadDdl(job) self.loadDdl(job)
for t in self.comp.conf[B.DATA_NODE_DDL]: for t in self.comp.conf[B.DATA_NODE_DDL]:
print("zu loeschende Tabelle "+t) print("zu loeschende Tabelle "+t)
self.deleteRows(t, job) self.deleteRows(job, t)
def deleteRows(self, table, job): def deleteRows(self, job, table):
""" method to delete rows from a database """ method to delete rows from a database
statement written in sql """ statement written in sql """
raise Exception(B.EXCEPT_NOT_IMPLEMENT) raise Exception(B.EXCEPT_NOT_IMPLEMENT)
@ -348,12 +386,12 @@ class DbFcts():
for t in tdata[B.DATA_NODE_TABLES]: for t in tdata[B.DATA_NODE_TABLES]:
print("einzufuegende Tabelle "+self.comp.name+" "+t) print("einzufuegende Tabelle "+self.comp.name+" "+t)
if isCompTable(self.comp, job, tdata, t): if isCompTable(self.comp, job, tdata, t):
self.insertRows(t, tdata[B.DATA_NODE_TABLES][t][B.DATA_NODE_DATA], job) self.insertRows(job, t, tdata[B.DATA_NODE_TABLES][t][B.DATA_NODE_DATA])
self.comp.m.logMsg("in Tabelle {} {} Zeilen eingefuegt".format( self.comp.m.logMsg("in Tabelle {} {} Zeilen eingefuegt".format(
t, len(tdata[B.DATA_NODE_TABLES][t][B.DATA_NODE_DATA]))) t, len(tdata[B.DATA_NODE_TABLES][t][B.DATA_NODE_DATA])))
def insertRows(self, rows): def insertRows(self, job, table, rows):
""" method to insert rows into a database """ method to insert rows into a database
the rows will be interpreted by the ddl of the component the rows will be interpreted by the ddl of the component
""" """
@ -386,8 +424,8 @@ class DbFcts():
if D.DDL_CONSTRAINT not in fo or fo[D.DDL_CONSTRAINT] == B.SVAL_YES: if D.DDL_CONSTRAINT not in fo or fo[D.DDL_CONSTRAINT] == B.SVAL_YES:
return self.getDbNull() return self.getDbNull()
if fo[D.DATA_NODE_TYPE] == D.TYPE_STRING or fo[D.DATA_NODE_TYPE] == D.TYPE_STR: if fo[D.DATA_NODE_TYPE] == D.TYPE_STRING or fo[D.DATA_NODE_TYPE] == D.TYPE_STR:
return value.strip() return "\'"+value.strip()+"\'"
elif fo[D.DATA_NODE_TYPE] == D.TYPE_INT: elif fo[D.DATA_NODE_TYPE] in [D.TYPE_INT, D.TYPE_PK]:
return value.strip() return value.strip()
elif fo[D.DATA_NODE_TYPE] == D.TYPE_DOUBLE: elif fo[D.DATA_NODE_TYPE] == D.TYPE_DOUBLE:
return self.getDbDouble(value) return self.getDbDouble(value)

10
tools/dbcsv_tool.py

@ -23,7 +23,7 @@ class DbFcts(tools.db_abstract.DbFcts):
def selectRows(self, table, job): def selectRows(self, table, job):
""" method to select rows from a database """ method to select rows from a database
statement written in sql """ statement written in sql """
sqlTable = tools.db_abstract.getSqlTable(self.comp, table) sqlTable = tools.db_abstract.getSqlTable(job, self.comp, table)
header = "" header = ""
path = utils.path_tool.composePattern(job, "{env.dompath}/"+sqlTable+".csv", self.comp) path = utils.path_tool.composePattern(job, "{env.dompath}/"+sqlTable+".csv", self.comp)
print(path) print(path)
@ -39,11 +39,11 @@ class DbFcts(tools.db_abstract.DbFcts):
return tdata return tdata
def deleteRows(self, table, job): def deleteRows(self, job, table):
""" method to delete rows from a database """ method to delete rows from a database
statement written in sql """ statement written in sql """
verify = -1+job.getDebugLevel("db_tool") verify = -1+job.getDebugLevel("db_tool")
sqlTable = tools.db_abstract.getSqlTable(self.comp, table) sqlTable = tools.db_abstract.getSqlTable(job, self.comp, table)
header = "" header = ""
path = utils.path_tool.composePattern(job, "{env.dompath}/"+sqlTable+".csv", self.comp) path = utils.path_tool.composePattern(job, "{env.dompath}/"+sqlTable+".csv", self.comp)
for h in self.comp.conf[B.DATA_NODE_DDL][table][B.DATA_NODE_HEADER]: for h in self.comp.conf[B.DATA_NODE_DDL][table][B.DATA_NODE_HEADER]:
@ -60,12 +60,12 @@ class DbFcts(tools.db_abstract.DbFcts):
raise Exception(B.EXCEPT_NOT_IMPLEMENT) raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def insertRows(self, table, rows, job): def insertRows(self, job, table, rows):
""" method to insert rows into a database """ method to insert rows into a database
the rows will be interpreted by the ddl of the component the rows will be interpreted by the ddl of the component
""" """
verify = -1+job.getDebugLevel("db_tool") verify = -1+job.getDebugLevel("db_tool")
sqlTable = tools.db_abstract.getSqlTable(self.comp, table) sqlTable = tools.db_abstract.getSqlTable(job, self.comp, table)
header = "" header = ""
path = utils.path_tool.composePattern(job, "{env.dompath}/"+sqlTable+".csv", self.comp) path = utils.path_tool.composePattern(job, "{env.dompath}/"+sqlTable+".csv", self.comp)
if len(rows) == 0: if len(rows) == 0:

20
tools/dbmysql_tool.py

@ -25,7 +25,7 @@ class DbFcts(tools.dbrel_tool.DbFcts):
statement written in sql """ statement written in sql """
tdata = {} tdata = {}
verify = -1+job.getDebugLevel("db_tool") verify = -1+job.getDebugLevel("db_tool")
attr = self.getDbAttributes(B.SVAL_NULL) attr = self.getDbAttributes(job, B.SVAL_NULL)
sql = "SELECT * FROM "+attr[B.ATTR_DB_DATABASE]+"."+table sql = "SELECT * FROM "+attr[B.ATTR_DB_DATABASE]+"."+table
if len(where) > 3: if len(where) > 3:
sql += " "+where sql += " "+where
@ -43,20 +43,23 @@ class DbFcts(tools.dbrel_tool.DbFcts):
r = {} r = {}
i = 0 i = 0
for f in self.comp.conf[B.DATA_NODE_DDL][table][B.DATA_NODE_HEADER]: for f in self.comp.conf[B.DATA_NODE_DDL][table][B.DATA_NODE_HEADER]:
try:
if self.comp.conf[B.DATA_NODE_DDL][table][f][D.DDL_TYPE] in [D.TYPE_TIME, D.TYPE_DATE]: if self.comp.conf[B.DATA_NODE_DDL][table][f][D.DDL_TYPE] in [D.TYPE_TIME, D.TYPE_DATE]:
r[f] = tools.date_tool.getFormatdate(x[i], tools.date_tool.F_DIR) r[f] = tools.date_tool.getFormatdate(x[i], tools.date_tool.F_DIR)
else: else:
r[f] = str(x[i]) r[f] = str(x[i])
except:
pass
i += 1 i += 1
tdata[B.DATA_NODE_DATA].append(r) tdata[B.DATA_NODE_DATA].append(r)
self.comp.m.logInfo(str(tdata)) self.comp.m.logInfo(str(tdata))
return tdata return tdata
def deleteRows(self, table, job, where=""): def deleteRows(self, job, table, where=""):
""" method to delete rows from a database """ method to delete rows from a database
statement written in sql """ statement written in sql """
verify = -1+job.getDebugLevel("db_tool") verify = -1+job.getDebugLevel("db_tool")
attr = self.getDbAttributes(B.SVAL_NULL) attr = self.getDbAttributes(job, B.SVAL_NULL)
sql = "DELETE FROM "+attr[B.ATTR_DB_DATABASE]+"."+table sql = "DELETE FROM "+attr[B.ATTR_DB_DATABASE]+"."+table
if len(where) > 3: if len(where) > 3:
sql += " "+where sql += " "+where
@ -69,12 +72,12 @@ class DbFcts(tools.dbrel_tool.DbFcts):
statement written in sql """ statement written in sql """
raise Exception(B.EXCEPT_NOT_IMPLEMENT) raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def insertRows(self, table, rows, job): def insertRows(self, job, table, rows):
""" method to insert rows into a database """ method to insert rows into a database
the rows will be interpreted by the ddl of the component the rows will be interpreted by the ddl of the component
""" """
verify = -1+job.getDebugLevel("db_tool") verify = -1+job.getDebugLevel("db_tool")
attr = self.getDbAttributes(B.SVAL_NULL) attr = self.getDbAttributes(job, B.SVAL_NULL)
insheader = self.getInsertFields(self.comp.conf[B.DATA_NODE_DDL][table]) insheader = self.getInsertFields(self.comp.conf[B.DATA_NODE_DDL][table])
if len(insheader) < len(self.comp.conf[B.DATA_NODE_DDL][table][B.DATA_NODE_HEADER]): if len(insheader) < len(self.comp.conf[B.DATA_NODE_DDL][table][B.DATA_NODE_HEADER]):
lastid = 1 lastid = 1
@ -89,9 +92,10 @@ class DbFcts(tools.dbrel_tool.DbFcts):
rowvalues = [] rowvalues = []
for h in insheader: for h in insheader:
if (h in r): if (h in r):
rowvalues.append("\'"+self.getDbValue(self.comp.conf[B.DATA_NODE_DDL][table][h], r[h])+"\'") #rowvalues.append("\'"+self.getDbValue(self.comp.conf[B.DATA_NODE_DDL][table][h], r[h])+"\'")
rowvalues.append(self.getDbValue(self.comp.conf[B.DATA_NODE_DDL][table][h], r[h]))
else: else:
rowvalues.append("\'"+self.getDbValue(self.comp.conf[B.DATA_NODE_DDL][table][h], "")+"\'") rowvalues.append(self.getDbValue(self.comp.conf[B.DATA_NODE_DDL][table][h], ""))
sql += "("+",".join(rowvalues)+"), " sql += "("+",".join(rowvalues)+"), "
values.append(tuple(rowvalues)) values.append(tuple(rowvalues))
sql = sql[0:-2] sql = sql[0:-2]
@ -129,7 +133,7 @@ class DbFcts(tools.dbrel_tool.DbFcts):
this method should only called by the class itself """ this method should only called by the class itself """
job = self.job # basic.program.Job.getInstance() job = self.job # basic.program.Job.getInstance()
if conn is None: if conn is None:
conn = self.getDbAttributes(B.SVAL_NULL) conn = self.getDbAttributes(job, B.SVAL_NULL)
cnx = mysql.connector.connect( cnx = mysql.connector.connect(
host=conn[B.ATTR_DB_HOST], host=conn[B.ATTR_DB_HOST],
user=conn[B.ATTR_DB_USER], user=conn[B.ATTR_DB_USER],

28
tools/dbrel_tool.py

@ -35,7 +35,7 @@ class DbFcts(tools.db_abstract.DbFcts):
self.comp.m.logInfo(cmd) self.comp.m.logInfo(cmd)
return tdata return tdata
def deleteRows(self, table, job): def deleteRows(self, job, table):
""" method to delete rows from a database """ method to delete rows from a database
statement written in sql """ statement written in sql """
verify = -1+job.getDebugLevel("db_tool") verify = -1+job.getDebugLevel("db_tool")
@ -47,7 +47,7 @@ class DbFcts(tools.db_abstract.DbFcts):
statement written in sql """ statement written in sql """
raise Exception(B.EXCEPT_NOT_IMPLEMENT) raise Exception(B.EXCEPT_NOT_IMPLEMENT)
def insertRows(self, table, rows, job): def insertRows(self, job, table, rows):
""" method to insert rows into a database """ method to insert rows into a database
the rows will be interpreted by the ddl of the component the rows will be interpreted by the ddl of the component
""" """
@ -75,17 +75,6 @@ class DbFcts(tools.db_abstract.DbFcts):
cmd = cmd[0:-1]+";" cmd = cmd[0:-1]+";"
self.comp.m.logInfo(cmd) self.comp.m.logInfo(cmd)
def getConnector(self):
""" add-on-method to get the connector
this method should only called by the class itself """
job = self.job # basic.program.Job.getInstance()
mydb = mysql.connector.connect(
host = "localhost",
user = "datest",
password = "Advent!2021",
database = "datest"
)
return mysql
def getCreateTable(self, table): def getCreateTable(self, table):
sql = "CREATE TABLE IF NOT EXISTS " + self.job.conf[B.TOPIC_NODE_DB][B.ATTR_DB_DATABASE] + "."+table+" (" sql = "CREATE TABLE IF NOT EXISTS " + self.job.conf[B.TOPIC_NODE_DB][B.ATTR_DB_DATABASE] + "."+table+" ("
return sql return sql
@ -127,19 +116,6 @@ class DbFcts(tools.db_abstract.DbFcts):
sql += " ( " + attr + " );" sql += " ( " + attr + " );"
return sql return sql
def getConnector(self, job):
""" add-on-method to get the connector
this method should only called by the class itself """
job = self.job # basic.program.Job.getInstance()
mydb = mysql.connector.connect(
host = "localhost",
user = "datest",
password = "Advent!2021",
database = "datest"
)
return mysql
@staticmethod @staticmethod
def execStatement(self, statement, conn=None): def execStatement(self, statement, conn=None):
""" add-on-method to execute the statement """ add-on-method to execute the statement

5
tools/path_const.py

@ -14,6 +14,7 @@ KEY_REFFILE = "reffile"
KEY_TESTCASE = "tc" KEY_TESTCASE = "tc"
KEY_TESTSUITE = "ts" KEY_TESTSUITE = "ts"
KEY_CATALOG = "catalog" KEY_CATALOG = "catalog"
KEY_USER = "user"
KEY_DEBUGNAME = "debugname" KEY_DEBUGNAME = "debugname"
KEY_LOGNAME = "logname" KEY_LOGNAME = "logname"
KEY_BASIC = "basic" KEY_BASIC = "basic"
@ -28,6 +29,8 @@ VAL_CONFIG = "config"
""" subdir for any place of config-files """ """ subdir for any place of config-files """
VAL_COMPS = "components" VAL_COMPS = "components"
""" subdir for the plugin components """ """ subdir for the plugin components """
VAL_USER = "user"
""" subdir for the created user """
VAL_BASIC = "basic" VAL_BASIC = "basic"
""" subdir for the basic job-framework """ """ subdir for the basic job-framework """
VAL_BASE_DATA = "data" VAL_BASE_DATA = "data"
@ -73,6 +76,8 @@ ATTR_PATH_PROGRAM = "program"
""" This constant defines the program-folder in the workspace """ """ This constant defines the program-folder in the workspace """
ATTR_PATH_COMPONENTS = "components" ATTR_PATH_COMPONENTS = "components"
""" This constant defines the program-folder in the workspace """ """ This constant defines the program-folder in the workspace """
ATTR_PATH_MODEL = "model"
""" This constant defines the folder in model """
ATTR_PATH_ENV = "environment" ATTR_PATH_ENV = "environment"
""" This constant defines the folder in testing-filesystem, used for configs related to environments """ """ This constant defines the folder in testing-filesystem, used for configs related to environments """
ATTR_PATH_RELEASE = "release" ATTR_PATH_RELEASE = "release"

Loading…
Cancel
Save