APplusJob implementiert
This commit is contained in:
parent
599339a270
commit
a5a107c9ea
@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 23.08.2023 v1.1.1
|
||||||
|
- `APplusJob` für einfachen Zugriff auf `p2core.Job` implementiert
|
||||||
|
- Funktion für Ausführung von DB-Anpass Dateien implementiert
|
||||||
|
|
||||||
## 27.07.2023 v1.1.0
|
## 27.07.2023 v1.1.0
|
||||||
- implementiere Zugriff auf ASMX Seiten
|
- implementiere Zugriff auf ASMX Seiten
|
||||||
- `getClient` -> `getAppClient` umbenannt
|
- `getClient` -> `getAppClient` umbenannt
|
||||||
|
@ -20,6 +20,14 @@ PyAPplus64.applus\_db module
|
|||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
PyAPplus64.applus\_job module
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
.. automodule:: PyAPplus64.applus_job
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
|
|
||||||
PyAPplus64.applus\_scripttool module
|
PyAPplus64.applus\_scripttool module
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "PyAPplus64"
|
name = "PyAPplus64"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
authors = [
|
authors = [
|
||||||
{ name="Thomas Tuerk", email="kontakt@thomas-tuerk.de" },
|
{ name="Thomas Tuerk", email="kontakt@thomas-tuerk.de" },
|
||||||
]
|
]
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
# https://opensource.org/licenses/MIT.
|
# https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
from . import applus_db
|
from . import applus_db
|
||||||
|
from . import applus_job
|
||||||
from . import applus_server
|
from . import applus_server
|
||||||
from . import applus_sysconf
|
from . import applus_sysconf
|
||||||
from . import applus_scripttool
|
from . import applus_scripttool
|
||||||
@ -56,12 +57,17 @@ class APplusServer:
|
|||||||
self.sysconf: applus_sysconf.APplusSysConf = applus_sysconf.APplusSysConf(self)
|
self.sysconf: applus_sysconf.APplusSysConf = applus_sysconf.APplusSysConf(self)
|
||||||
"""erlaubt den Zugriff auf die Sysconfig"""
|
"""erlaubt den Zugriff auf die Sysconfig"""
|
||||||
|
|
||||||
|
self.job: applus_job.APplusJob = applus_job.APplusJob(self)
|
||||||
|
"""erlaubt Arbeiten mit Jobs"""
|
||||||
|
|
||||||
self.scripttool: applus_scripttool.APplusScriptTool = applus_scripttool.APplusScriptTool(self)
|
self.scripttool: applus_scripttool.APplusScriptTool = applus_scripttool.APplusScriptTool(self)
|
||||||
"""erlaubt den einfachen Zugriff auf Funktionen des ScriptTools"""
|
"""erlaubt den einfachen Zugriff auf Funktionen des ScriptTools"""
|
||||||
|
|
||||||
self.client_table = self.server_conn.getAppClient("p2core", "Table")
|
self.client_table = self.server_conn.getAppClient("p2core", "Table")
|
||||||
self.client_xml = self.server_conn.getAppClient("p2core", "XML")
|
self.client_xml = self.server_conn.getAppClient("p2core", "XML")
|
||||||
self.client_nummer = self.server_conn.getAppClient("p2system", "Nummer")
|
self.client_nummer = self.server_conn.getAppClient("p2system", "Nummer")
|
||||||
|
self.client_adaptdb = self.server_conn.getAppClient("p2dbtools", "AdaptDB");
|
||||||
|
|
||||||
|
|
||||||
def reconnectDB(self) -> None:
|
def reconnectDB(self) -> None:
|
||||||
try:
|
try:
|
||||||
@ -123,6 +129,12 @@ class APplusServer:
|
|||||||
sqlC = self.completeSQL(sql, raw=raw)
|
sqlC = self.completeSQL(sql, raw=raw)
|
||||||
return applus_db.rawQuerySingleValue(self.db_conn, sqlC, *args)
|
return applus_db.rawQuerySingleValue(self.db_conn, sqlC, *args)
|
||||||
|
|
||||||
|
def dbExecute(self, sql: sql_utils.SqlStatement, *args: Any, raw: bool = False) -> Any:
|
||||||
|
"""Führt ein SQL Statement (z.B. update oder insert) aus. Das SQL wird zunächst
|
||||||
|
vom Server angepasst, so dass z.B. Mandanteninformation hinzugefügt werden."""
|
||||||
|
sqlC = self.completeSQL(sql, raw=raw)
|
||||||
|
return applus_db.rawExecute(self.db_conn, sqlC, *args)
|
||||||
|
|
||||||
def isDBTableKnown(self, table: str) -> bool:
|
def isDBTableKnown(self, table: str) -> bool:
|
||||||
"""Prüft, ob eine Tabelle im System bekannt ist"""
|
"""Prüft, ob eine Tabelle im System bekannt ist"""
|
||||||
sql = "select count(*) from SYS.TABLES T where T.NAME=?"
|
sql = "select count(*) from SYS.TABLES T where T.NAME=?"
|
||||||
@ -231,6 +243,24 @@ class APplusServer:
|
|||||||
"""
|
"""
|
||||||
return self.client_nummer.service.nextNumber(obj)
|
return self.client_nummer.service.nextNumber(obj)
|
||||||
|
|
||||||
|
def updateDatabase(self, file : str) -> str:
|
||||||
|
"""
|
||||||
|
Führt eine DBAnpass-xml Datei aus.
|
||||||
|
:param file: DB-Anpass Datei, die ausgeführt werden soll
|
||||||
|
:type file: string
|
||||||
|
:return: Infos zur Ausführung
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
jobId = self.job.createSOAPJob("run DBAnpass " + file);
|
||||||
|
self.client_adaptdb.service.updateDatabase(jobId, "de", file);
|
||||||
|
res = self.job.getResultURLString(jobId)
|
||||||
|
if res is None: res = "FEHLER";
|
||||||
|
if (res == "Folgende Befehle konnten nicht ausgeführt werden:\n\n"):
|
||||||
|
return ""
|
||||||
|
else:
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
def makeWebLink(self, base: str, **kwargs: Any) -> str:
|
def makeWebLink(self, base: str, **kwargs: Any) -> str:
|
||||||
if not self.server_settings.webserver:
|
if not self.server_settings.webserver:
|
||||||
raise Exception("keine Webserver-BaseURL gesetzt")
|
raise Exception("keine Webserver-BaseURL gesetzt")
|
||||||
|
@ -108,6 +108,11 @@ def rawQuerySingleValue(cnxn: pyodbc.Connection, sql: SqlStatement, *args: Any)
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def rawExecute(cnxn: pyodbc.Connection, sql: SqlStatement, *args: Any) -> Any:
|
||||||
|
"""Führt ein SQL Statement direkt aus"""
|
||||||
|
_logSQLWithArgs(sql, *args)
|
||||||
|
with cnxn.cursor() as cursor:
|
||||||
|
return cursor.execute(str(sql), *args)
|
||||||
|
|
||||||
def getUniqueFieldsOfTable(cnxn: pyodbc.Connection, table: str) -> Dict[str, List[str]]:
|
def getUniqueFieldsOfTable(cnxn: pyodbc.Connection, table: str) -> Dict[str, List[str]]:
|
||||||
"""
|
"""
|
||||||
|
195
src/PyAPplus64/applus_job.py
Normal file
195
src/PyAPplus64/applus_job.py
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
# Copyright (c) 2023 Thomas Tuerk (kontakt@thomas-tuerk.de)
|
||||||
|
#
|
||||||
|
# This file is part of PyAPplus64 (see https://www.thomas-tuerk.de/de/pyapplus64).
|
||||||
|
#
|
||||||
|
# Use of this source code is governed by an MIT-style
|
||||||
|
# license that can be found in the LICENSE file or at
|
||||||
|
# https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .applus import APplusServer
|
||||||
|
|
||||||
|
|
||||||
|
class APplusJob:
|
||||||
|
"""
|
||||||
|
Zugriff auf Jobs
|
||||||
|
|
||||||
|
:param server: die Verbindung zum Server
|
||||||
|
:type server: APplusServer
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, server: 'APplusServer') -> None:
|
||||||
|
self.client = server.getAppClient("p2core", "Job")
|
||||||
|
|
||||||
|
def createSOAPJob(self, bez: str) -> str:
|
||||||
|
"""
|
||||||
|
Erzeugt einen neuen SOAP Job mit der gegebenen Bezeichnung und liefert die neue JobID.
|
||||||
|
:param bez: die Bezeichnung des neuen Jobs
|
||||||
|
:type bez: str
|
||||||
|
:return: die neue JobID
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
jobId = str(uuid.uuid4())
|
||||||
|
self.client.service.create(jobId, "SOAP", "0", "about:soapcall", bez)
|
||||||
|
return jobId
|
||||||
|
|
||||||
|
def restart(self, jobId: str) -> str:
|
||||||
|
"""
|
||||||
|
Startet einen Job neu
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:return: die URL des Jobs
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self.client.service.restart(jobId)
|
||||||
|
|
||||||
|
def setResultURL(self, jobId: str, resurl: str) -> None:
|
||||||
|
"""
|
||||||
|
Setzt die ResultURL eines Jobs
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:param resurl: die neue Result-URL
|
||||||
|
:type resurl: str
|
||||||
|
"""
|
||||||
|
self.client.service.setResultURL(jobId, resurl)
|
||||||
|
|
||||||
|
def getResultURL(self, jobId: str) -> str:
|
||||||
|
"""
|
||||||
|
Liefert die ResultURL eines Jobs
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:return: die Result-URL
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self.client.service.getResultURL(jobId)
|
||||||
|
|
||||||
|
def getResultURLString(self, jobId: str) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Liefert die ResultURL eines Jobs, wobei ein evtl. Präfix "retstring://" entfernt wird und
|
||||||
|
alle anderen Werte durch None ersetzt werden.
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:return: die Result-URL als String
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
res = self.getResultURL(jobId)
|
||||||
|
if res is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if res.startswith("retstring://"):
|
||||||
|
return res[12:]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def setPtURL(self, jobId: str, pturl: str) -> None:
|
||||||
|
"""
|
||||||
|
Setzt die ResultURL eines Jobs
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:param pturl: die neue PtURL
|
||||||
|
:type pturl: str
|
||||||
|
"""
|
||||||
|
self.client.service.setPtURL(jobId, pturl)
|
||||||
|
|
||||||
|
def getPtURL(self, jobId: str) -> str:
|
||||||
|
"""
|
||||||
|
Liefert die PtURL eines Jobs
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:return: die Pt-URL
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self.client.service.getPtURL(jobId)
|
||||||
|
|
||||||
|
def setResult(self, jobId: str, res: str) -> None:
|
||||||
|
"""
|
||||||
|
Setzt das Result eines Jobs
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:param res: das neue Result
|
||||||
|
:type res: str
|
||||||
|
"""
|
||||||
|
self.client.service.setResult(jobId, res)
|
||||||
|
|
||||||
|
def getResult(self, jobId: str) -> str:
|
||||||
|
"""
|
||||||
|
Liefert das Result eines Jobs
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:return: das Result
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self.client.service.getResult(jobId)
|
||||||
|
|
||||||
|
def setInfo(self, jobId: str, info: str) -> bool:
|
||||||
|
"""
|
||||||
|
Setzt die Informationen zu dem Job
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:param info: die neuen Infos
|
||||||
|
:type info: str
|
||||||
|
"""
|
||||||
|
return self.client.service.setInfo(jobId, info)
|
||||||
|
|
||||||
|
def getInfo(self, jobId: str) -> str:
|
||||||
|
"""
|
||||||
|
Liefert die Info eines Jobs
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:return: die Info
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self.client.service.getInfo(jobId)
|
||||||
|
|
||||||
|
def getStatus(self, jobId: str) -> str:
|
||||||
|
"""
|
||||||
|
Liefert Informationen zum Job
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:return: die Infos
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
return self.client.service.getStatus(jobId)
|
||||||
|
|
||||||
|
def setPosition(self, jobId: str, pos: int, max: int) -> bool:
|
||||||
|
"""
|
||||||
|
Schrittfunktion
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:param pos: Position
|
||||||
|
:type pos: int
|
||||||
|
:param max: Anzahl Schritte in Anzeige
|
||||||
|
:type max: int
|
||||||
|
"""
|
||||||
|
return self.client.service.setPosition(jobId, pos, max)
|
||||||
|
|
||||||
|
def start(self, jobId: str) -> bool:
|
||||||
|
"""
|
||||||
|
Startet einen Job
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
"""
|
||||||
|
return self.client.service.start(jobId)
|
||||||
|
|
||||||
|
def kill(self, jobId: str) -> None:
|
||||||
|
"""
|
||||||
|
Startet einen Job
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
"""
|
||||||
|
self.client.service.start(jobId)
|
||||||
|
|
||||||
|
def finish(self, jobId: str, status: int, resurl: str) -> bool:
|
||||||
|
"""
|
||||||
|
Beendet den Job
|
||||||
|
:param jobId: die ID des Jobs
|
||||||
|
:type jobId: str
|
||||||
|
:param status: der Status 2 (OK), 3 (Fehler)
|
||||||
|
:type status: int
|
||||||
|
:param resurl: die neue resurl des Jobs
|
||||||
|
:type resurl: str
|
||||||
|
"""
|
||||||
|
return self.client.service.finish(jobId, status, resurl)
|
@ -392,7 +392,7 @@ class SqlConditionBinComp(SqlConditionPrepared):
|
|||||||
:type value2: SqlValue
|
:type value2: SqlValue
|
||||||
"""
|
"""
|
||||||
def __init__(self, op: str, value1: SqlValue, value2: SqlValue):
|
def __init__(self, op: str, value1: SqlValue, value2: SqlValue):
|
||||||
if not value1 or not value2:
|
if value1 is None or value2 is None:
|
||||||
raise Exception("SqlConditionBinComp: value not provided")
|
raise Exception("SqlConditionBinComp: value not provided")
|
||||||
|
|
||||||
cond = "({} {} {})".format(formatSqlValue(value1), op, formatSqlValue(value2))
|
cond = "({} {} {})".format(formatSqlValue(value1), op, formatSqlValue(value2))
|
||||||
|
Loading…
Reference in New Issue
Block a user