wwpdb.utils.wf 0.43__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.
- wwpdb/utils/wf/DataSelector.py +106 -0
- wwpdb/utils/wf/DataValueContainer.py +158 -0
- wwpdb/utils/wf/WfDataObject.py +89 -0
- wwpdb/utils/wf/__init__.py +5 -0
- wwpdb/utils/wf/dbapi/DbApiUtil.py +237 -0
- wwpdb/utils/wf/dbapi/DbCommand.py +456 -0
- wwpdb/utils/wf/dbapi/DbConnection.py +156 -0
- wwpdb/utils/wf/dbapi/LocalDbApi.py +80 -0
- wwpdb/utils/wf/dbapi/StatusDbApi.py +100 -0
- wwpdb/utils/wf/dbapi/WFEtime.py +49 -0
- wwpdb/utils/wf/dbapi/WfDbApi.py +1237 -0
- wwpdb/utils/wf/dbapi/WfTracking.py +114 -0
- wwpdb/utils/wf/dbapi/__init__.py +0 -0
- wwpdb/utils/wf/dbapi/dbAPI.py +329 -0
- wwpdb/utils/wf/plugins/AnnotationUtils.py +1516 -0
- wwpdb/utils/wf/plugins/ChemCompUtils.py +262 -0
- wwpdb/utils/wf/plugins/DepositUtils.py +46 -0
- wwpdb/utils/wf/plugins/DictUtils.py +101 -0
- wwpdb/utils/wf/plugins/DpUtils.py +130 -0
- wwpdb/utils/wf/plugins/EmUtils.py +427 -0
- wwpdb/utils/wf/plugins/FileUtils.py +256 -0
- wwpdb/utils/wf/plugins/FormatUtils.py +297 -0
- wwpdb/utils/wf/plugins/NmrUtils.py +1122 -0
- wwpdb/utils/wf/plugins/PcmCsvUtils.py +74 -0
- wwpdb/utils/wf/plugins/PdbxUtils.py +520 -0
- wwpdb/utils/wf/plugins/PrdSearchUtils.py +100 -0
- wwpdb/utils/wf/plugins/ReportUtils.py +95 -0
- wwpdb/utils/wf/plugins/SeqStatsUtils.py +163 -0
- wwpdb/utils/wf/plugins/SeqdbUtils.py +276 -0
- wwpdb/utils/wf/plugins/UtilsBase.py +52 -0
- wwpdb/utils/wf/plugins/ValidationUtils.py +606 -0
- wwpdb/utils/wf/plugins/__init__.py +0 -0
- wwpdb/utils/wf/process/ActionRegistry.py +514 -0
- wwpdb/utils/wf/process/ActionRegistryIo.py +202 -0
- wwpdb/utils/wf/process/ProcessRunner.py +276 -0
- wwpdb/utils/wf/process/__init__.py +0 -0
- wwpdb/utils/wf/schema/WfSchemaMap.py +366 -0
- wwpdb/utils/wf/schema/__init__.py +0 -0
- wwpdb/utils/wf/schema/database_descriptions.txt +339 -0
- wwpdb/utils/wf/schema/mandatory_items.txt +21 -0
- wwpdb_utils_wf-0.43.dist-info/METADATA +49 -0
- wwpdb_utils_wf-0.43.dist-info/RECORD +44 -0
- wwpdb_utils_wf-0.43.dist-info/WHEEL +4 -0
- wwpdb_utils_wf-0.43.dist-info/licenses/LICENSE +12 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
##
|
|
2
|
+
# File: DataSelector.py
|
|
3
|
+
# Date: 5-April-2010
|
|
4
|
+
#
|
|
5
|
+
# Updates:
|
|
6
|
+
#
|
|
7
|
+
##
|
|
8
|
+
"""
|
|
9
|
+
Container for data selection criteria.
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
__docformat__ = "restructuredtext en"
|
|
14
|
+
__author__ = "John Westbrook"
|
|
15
|
+
__email__ = "jwest@rcsb.rutgers.edu"
|
|
16
|
+
__license__ = "Creative Commons Attribution 3.0 Unported"
|
|
17
|
+
__version__ = "V0.01"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DataSelector:
|
|
21
|
+
"""A container for data selection criteria.
|
|
22
|
+
|
|
23
|
+
A selector defines the following parameters:
|
|
24
|
+
|
|
25
|
+
- targetCategoryName name of category to which selection is applied
|
|
26
|
+
- targetAttributeNameList [attributeName, attributeName,...] the values of the
|
|
27
|
+
attributes in this list will be returned subject to the selection condition.
|
|
28
|
+
|
|
29
|
+
Selection conditions are stored as a list of tuples of name, value and operator:
|
|
30
|
+
|
|
31
|
+
- conditionList [(attributeName,attributeValue,comparisonOp),,...]
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
super(DataSelector, self).__init__()
|
|
37
|
+
# self.__verbose = False
|
|
38
|
+
# sys.stderr.write("DataSelector.__init_()\n")
|
|
39
|
+
self.__selectorType = None
|
|
40
|
+
#
|
|
41
|
+
self.__targetCategoryName = None
|
|
42
|
+
self.__targetAttributeList = []
|
|
43
|
+
self.__selectConditionList = []
|
|
44
|
+
|
|
45
|
+
def getSelectorType(self):
|
|
46
|
+
"""Get the type of selector type. Currently only attribute value selections are supported."""
|
|
47
|
+
return self.__selectorType
|
|
48
|
+
|
|
49
|
+
def setSelectCategoryName(self, categoryName):
|
|
50
|
+
"""Set the target category for this selection.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
|
|
54
|
+
True for success or False otherwise
|
|
55
|
+
"""
|
|
56
|
+
try:
|
|
57
|
+
self.__targetCategoryName = categoryName
|
|
58
|
+
return True
|
|
59
|
+
except: # noqa: E722 pylint: disable=bare-except
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
def getSelectCategoryName(self):
|
|
63
|
+
"""Get the taget category for this selection."""
|
|
64
|
+
return self.__targetCategoryName
|
|
65
|
+
|
|
66
|
+
def addSelectAttributeName(self, attributeName):
|
|
67
|
+
"""Add an attribute to the list of attributes for this selection.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
|
|
71
|
+
True for success or False otherwise
|
|
72
|
+
"""
|
|
73
|
+
try:
|
|
74
|
+
if attributeName not in self.__targetAttributeList:
|
|
75
|
+
self.__targetAttributeList.append(attributeName)
|
|
76
|
+
self.__selectorType = "attribute"
|
|
77
|
+
return True
|
|
78
|
+
except: # noqa: E722 pylint: disable=bare-except
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
def getSelectAttributeList(self):
|
|
82
|
+
"""Get the list attributes for the current selection"""
|
|
83
|
+
return self.__targetAttributeList
|
|
84
|
+
|
|
85
|
+
def addSelectCondition(self, attributeName, attributeValue, comparisonOp="equal"):
|
|
86
|
+
"""Add a selection condition to the current selection.
|
|
87
|
+
|
|
88
|
+
A selection condition contains the following:
|
|
89
|
+
- attributeName in the target category.
|
|
90
|
+
- attributeValue
|
|
91
|
+
- one of the comparison operators (equals, ...)
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
|
|
95
|
+
True for success or False otherwise.
|
|
96
|
+
|
|
97
|
+
"""
|
|
98
|
+
try:
|
|
99
|
+
self.__selectConditionList.append((attributeName, attributeValue, comparisonOp))
|
|
100
|
+
return True
|
|
101
|
+
except: # noqa: E722 pylint: disable=bare-except
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
def getSelectConditionList(self):
|
|
105
|
+
"""Get the list selection conditions."""
|
|
106
|
+
return self.__selectConditionList
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
##
|
|
2
|
+
# File: DataValueContainer.py
|
|
3
|
+
# Date: 28-Mar-2010
|
|
4
|
+
#
|
|
5
|
+
# Updates:
|
|
6
|
+
#
|
|
7
|
+
##
|
|
8
|
+
"""
|
|
9
|
+
Container for data values.
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
__docformat__ = "restructuredtext en"
|
|
14
|
+
__author__ = "John Westbrook"
|
|
15
|
+
__email__ = "jwest@rcsb.rutgers.edu"
|
|
16
|
+
__license__ = "Creative Commons Attribution 3.0 Unported"
|
|
17
|
+
__version__ = "V0.01"
|
|
18
|
+
|
|
19
|
+
# For python 2/3 compatible comparison with isinstace
|
|
20
|
+
from builtins import str # noqa: UP029,A004
|
|
21
|
+
from datetime import date, datetime
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DataValueContainer:
|
|
25
|
+
"""Container for data values.
|
|
26
|
+
|
|
27
|
+
Supported container types include:
|
|
28
|
+
- individual bool, int, float, string, date, or datetime values
|
|
29
|
+
- lists of bool, int, float, string, date, datetime values
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self):
|
|
34
|
+
super(DataValueContainer, self).__init__()
|
|
35
|
+
# sys.stderr.write("DataValueContainer.__init_()\n")
|
|
36
|
+
#
|
|
37
|
+
self.__valueTypeName = None
|
|
38
|
+
""" A supported data type name such:
|
|
39
|
+
- boolean
|
|
40
|
+
- int or integer
|
|
41
|
+
- float or double
|
|
42
|
+
- string
|
|
43
|
+
- date
|
|
44
|
+
- datetime
|
|
45
|
+
"""
|
|
46
|
+
#
|
|
47
|
+
self.__valueType = type(None)
|
|
48
|
+
""" Intrinsic Python type corresponding to the valueTypeName.
|
|
49
|
+
|
|
50
|
+
Types are defined in the Python class `types`.
|
|
51
|
+
"""
|
|
52
|
+
#
|
|
53
|
+
self.__containerTypeName = None
|
|
54
|
+
""" Container type setting:
|
|
55
|
+
- value, a single value
|
|
56
|
+
- list, a list/vector of values
|
|
57
|
+
- dict, a dictionary of key/values pairs
|
|
58
|
+
|
|
59
|
+
"""
|
|
60
|
+
#
|
|
61
|
+
self.__value = None
|
|
62
|
+
|
|
63
|
+
def isValueValid(self):
|
|
64
|
+
"""Performs a sanity type check on the current value and container types.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
|
|
68
|
+
True if value and container types correspond to the current type settings or False otherwise.
|
|
69
|
+
"""
|
|
70
|
+
if self.__containerTypeName == "list":
|
|
71
|
+
if isinstance(self.__value, list):
|
|
72
|
+
for v in self.__value: # noqa: SIM110
|
|
73
|
+
if not isinstance(v, self.__valueType):
|
|
74
|
+
return False
|
|
75
|
+
return True
|
|
76
|
+
return False
|
|
77
|
+
if self.__containerTypeName == "dict":
|
|
78
|
+
if isinstance(self.__value, dict):
|
|
79
|
+
return True
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
if isinstance(self.__value, self.__valueType):
|
|
83
|
+
return True
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
def isValueSet(self):
|
|
87
|
+
"""Performs a check if the current data value has been set.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
|
|
91
|
+
True if the value has been set or False otherwise.
|
|
92
|
+
|
|
93
|
+
"""
|
|
94
|
+
return self.__value is not None
|
|
95
|
+
|
|
96
|
+
def setValue(self, value):
|
|
97
|
+
self.__value = value
|
|
98
|
+
|
|
99
|
+
def getValue(self):
|
|
100
|
+
return self.__value
|
|
101
|
+
|
|
102
|
+
def setValueTypeName(self, typeName):
|
|
103
|
+
"""Set the data type name for the container.
|
|
104
|
+
|
|
105
|
+
Supported types include:
|
|
106
|
+
- boolean
|
|
107
|
+
- int or integer
|
|
108
|
+
- float or double
|
|
109
|
+
- string
|
|
110
|
+
- date
|
|
111
|
+
- datetime -- no TZ aware form -- might need an update
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
|
|
115
|
+
True if the input typeName is a supported type or False otherwise.
|
|
116
|
+
"""
|
|
117
|
+
if str(typeName) in ["boolean", "int", "integer", "float", "double", "string", "date", "datetime"]:
|
|
118
|
+
self.__valueTypeName = str(typeName)
|
|
119
|
+
if typeName in ("bool", "boolean"):
|
|
120
|
+
self.__valueType = bool
|
|
121
|
+
elif typeName in ("integer", "int", "float", "double"):
|
|
122
|
+
self.__valueType = int
|
|
123
|
+
elif typeName == "string":
|
|
124
|
+
self.__valueType = str
|
|
125
|
+
elif typeName == "date":
|
|
126
|
+
tt = date(2010, 1, 1)
|
|
127
|
+
self.__valueType = tt.__class__
|
|
128
|
+
elif typeName == "datetime":
|
|
129
|
+
tt = datetime(2010, 1, 1) # noqa: DTZ001
|
|
130
|
+
self.__valueType = tt.__class__
|
|
131
|
+
else:
|
|
132
|
+
return False
|
|
133
|
+
return True
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
def setContainerTypeName(self, containerName):
|
|
137
|
+
"""Set the container type name.
|
|
138
|
+
|
|
139
|
+
Supported container types include:
|
|
140
|
+
- value, a individual value
|
|
141
|
+
- list, list or vector of values
|
|
142
|
+
- dict, dictionary of key,value pairs
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
|
|
146
|
+
True for supported container types or False otherwise.
|
|
147
|
+
|
|
148
|
+
"""
|
|
149
|
+
if containerName in ["value", "list", "dict"]:
|
|
150
|
+
self.__containerTypeName = containerName
|
|
151
|
+
return True
|
|
152
|
+
return False
|
|
153
|
+
|
|
154
|
+
def getContainerTypeName(self):
|
|
155
|
+
return self.__containerTypeName
|
|
156
|
+
|
|
157
|
+
def getValueTypeName(self):
|
|
158
|
+
return self.__valueTypeName
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
##
|
|
2
|
+
# File: WfDataObject.py
|
|
3
|
+
# Date: 5-April-2010
|
|
4
|
+
#
|
|
5
|
+
# Updates:
|
|
6
|
+
# 1-May-2015 jdw add common output method
|
|
7
|
+
# 7-Sep-2015 jdw add __str__ and __repl__
|
|
8
|
+
#
|
|
9
|
+
##
|
|
10
|
+
"""
|
|
11
|
+
Mixin container the workflow data object.
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
__docformat__ = "restructuredtext en"
|
|
16
|
+
__author__ = "John Westbrook"
|
|
17
|
+
__email__ = "jwest@rcsb.rutgers.edu"
|
|
18
|
+
__license__ = "Creative Commons Attribution 3.0 Unported"
|
|
19
|
+
__version__ = "V0.01"
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
import cStringIO as StringIO # type: ignore[import-not-found]
|
|
23
|
+
except ImportError:
|
|
24
|
+
import io as StringIO # noqa: N812
|
|
25
|
+
|
|
26
|
+
from wwpdb.io.locator.DataReference import DataFileReference
|
|
27
|
+
|
|
28
|
+
from wwpdb.utils.wf.DataSelector import DataSelector
|
|
29
|
+
from wwpdb.utils.wf.DataValueContainer import DataValueContainer
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class WfDataObject(DataSelector, DataValueContainer, DataFileReference):
|
|
33
|
+
"""Top-level container for workflow data object.
|
|
34
|
+
|
|
35
|
+
This container includes some combination of the following:
|
|
36
|
+
- A data file reference (`DataFileReference`)
|
|
37
|
+
- A data value container (`DataValueContainer`)
|
|
38
|
+
- A data selector (`DataSelector`)
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
# Inherit base __init__
|
|
43
|
+
# def __init__(self):
|
|
44
|
+
# super(WfDataObject, self).__init__()
|
|
45
|
+
# self.__verbose = False
|
|
46
|
+
# sys.stderr.write("WfDataObject.__init_()\n")
|
|
47
|
+
|
|
48
|
+
def printMe(self, ofh):
|
|
49
|
+
if self.getReferenceType() in ["file"]:
|
|
50
|
+
ofh.write("+WfDataObject.printMe() reference type %s\n" % self.getReferenceType())
|
|
51
|
+
ofh.write("+WfDataObject.printMe() version ID %s\n" % self.getVersionId())
|
|
52
|
+
ofh.write("+WfDataObject.printMe() data set ID %s\n" % self.getDepositionDataSetId())
|
|
53
|
+
ofh.write("+WfDataObject.printMe() partition number %s\n" % self.getPartitionNumber())
|
|
54
|
+
ofh.write("+WfDataObject.printMe() content type %s\n" % self.getContentType())
|
|
55
|
+
ofh.write("+WfDataObject.printMe() file format %s\n" % self.getFileFormat())
|
|
56
|
+
ofh.write("+WfDataObject.printMe() storage type %s\n" % self.getStorageType())
|
|
57
|
+
ofh.write("+WfDataObject.printMe() directory path %s\n" % self.getDirPathReference())
|
|
58
|
+
ofh.write("+WfDataObject.printMe() file path %s\n" % self.getFilePathReference())
|
|
59
|
+
if self.getSelectorType() is not None:
|
|
60
|
+
ofh.write("+WfDataObject.printMe() selector type %s\n" % self.getSelectorType())
|
|
61
|
+
ofh.write("+WfDataObject.printMe() select category %s\n" % self.getSelectCategoryName())
|
|
62
|
+
ofh.write("+WfDataObject.printMe() select attributes %r\n" % self.getSelectAttributeList())
|
|
63
|
+
ofh.write("+WfDataObject.printMe() select conditions %r\n" % self.getSelectConditionList())
|
|
64
|
+
elif self.getContainerTypeName() in ["value", "list", "dict"]:
|
|
65
|
+
ofh.write("+WfDataObject.printMe() container type %s\n" % self.getContainerTypeName())
|
|
66
|
+
ofh.write("+WfDataObject.printMe() value type %s\n" % self.getValueTypeName())
|
|
67
|
+
ofh.write("+WfDataObject.printMe() is value set %r\n" % self.isValueSet())
|
|
68
|
+
ofh.write("+WfDataObject.printMe() is value valid %r\n" % self.isValueValid())
|
|
69
|
+
ofh.write("+WfDataObject.printMe() data value %r\n" % self.getValue())
|
|
70
|
+
else:
|
|
71
|
+
ofh.write("+WfDataObject.printMe() undefined data object\n")
|
|
72
|
+
|
|
73
|
+
def __str__(self):
|
|
74
|
+
output = StringIO.StringIO()
|
|
75
|
+
self.printMe(ofh=output)
|
|
76
|
+
contents = output.getvalue()
|
|
77
|
+
output.close()
|
|
78
|
+
return contents
|
|
79
|
+
|
|
80
|
+
def __repr__(self):
|
|
81
|
+
output = StringIO.StringIO()
|
|
82
|
+
self.printMe(ofh=output)
|
|
83
|
+
contents = output.getvalue()
|
|
84
|
+
output.close()
|
|
85
|
+
return contents
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
wfd = WfDataObject()
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
##
|
|
2
|
+
# File: DbApiUtil.py
|
|
3
|
+
# Date: 04-May-2015
|
|
4
|
+
# Updates:
|
|
5
|
+
##
|
|
6
|
+
"""
|
|
7
|
+
Providing general APIs for database access
|
|
8
|
+
|
|
9
|
+
This software was developed as part of the World Wide Protein Data Bank
|
|
10
|
+
Common Deposition and Annotation System Project
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2015 wwPDB
|
|
13
|
+
|
|
14
|
+
This software is provided under a Creative Commons Attribution 3.0 Unported
|
|
15
|
+
License described at http://creativecommons.org/licenses/by/3.0/.
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
__docformat__ = "restructuredtext en"
|
|
20
|
+
__author__ = "Zukang Feng"
|
|
21
|
+
__email__ = "zfeng@rcsb.rutgers.edu"
|
|
22
|
+
__license__ = "Creative Commons Attribution 3.0 Unported"
|
|
23
|
+
__version__ = "V0.07"
|
|
24
|
+
|
|
25
|
+
import datetime
|
|
26
|
+
import os
|
|
27
|
+
import sys
|
|
28
|
+
import time
|
|
29
|
+
|
|
30
|
+
import MySQLdb
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
from wwpdb.utils.wf.dbapi.DbConnection import DbConnection
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DbApiUtil:
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
dbServer=None,
|
|
40
|
+
dbHost=None,
|
|
41
|
+
dbName=None,
|
|
42
|
+
dbUser=None,
|
|
43
|
+
dbPw=None,
|
|
44
|
+
dbSocket=None,
|
|
45
|
+
dbPort=None,
|
|
46
|
+
verbose=False,
|
|
47
|
+
log=sys.stderr,
|
|
48
|
+
):
|
|
49
|
+
""" """
|
|
50
|
+
self.__debug = False
|
|
51
|
+
self.__Nretry = 5
|
|
52
|
+
self.__dbServer = dbServer
|
|
53
|
+
self.__dbHost = dbHost
|
|
54
|
+
self.__dbName = dbName
|
|
55
|
+
self.__dbUser = dbUser
|
|
56
|
+
self.__dbPw = dbPw
|
|
57
|
+
self.__dbSocket = dbSocket
|
|
58
|
+
self.__dbPort = dbPort
|
|
59
|
+
self.__verbose = verbose # pylint: disable=unused-private-member
|
|
60
|
+
self.__lfh = log
|
|
61
|
+
self.__schemaMap = {}
|
|
62
|
+
self.__dbState = 0
|
|
63
|
+
|
|
64
|
+
if self.__debug:
|
|
65
|
+
self.__lfh.write("\n+DbApiUtil.__init__() using socket %r\n" % self.__dbSocket)
|
|
66
|
+
self.__lfh.write("+DbApiUtil.__init__() using socket environment reference %r\n" % os.getenv("SITE_DB_SOCKET", None))
|
|
67
|
+
|
|
68
|
+
self.__myDb = DbConnection(
|
|
69
|
+
dbServer=self.__dbServer,
|
|
70
|
+
dbHost=self.__dbHost,
|
|
71
|
+
dbName=self.__dbName,
|
|
72
|
+
dbUser=self.__dbUser,
|
|
73
|
+
dbPw=self.__dbPw,
|
|
74
|
+
dbPort=self.__dbPort,
|
|
75
|
+
dbSocket=self.__dbSocket,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
self.__dbcon = self.__myDb.connect()
|
|
79
|
+
|
|
80
|
+
def __reConnect(self):
|
|
81
|
+
""" """
|
|
82
|
+
try:
|
|
83
|
+
self.__myDb.close(self.__dbcon)
|
|
84
|
+
except MySQLdb.Error:
|
|
85
|
+
self.__lfh.write("+DbApiUtil.reConnect() DB connection lost - cannot close\n")
|
|
86
|
+
self.__lfh.write("+DbApiUtil.reConnect() Re-connecting to the database ..\n")
|
|
87
|
+
self.__lfh.write("+DbApiUtil.reConnect() UTC time = %s\n" % datetime.datetime.utcnow()) # noqa: DTZ003
|
|
88
|
+
|
|
89
|
+
for i in range(1, self.__Nretry):
|
|
90
|
+
try:
|
|
91
|
+
self.__dbcon = self.__myDb.connect()
|
|
92
|
+
self.__dbState = 0
|
|
93
|
+
return True
|
|
94
|
+
except MySQLdb.Error:
|
|
95
|
+
self.__lfh.write("+DbApiUtil.reConnect() Cannot get re-connection : trying again\n")
|
|
96
|
+
time.sleep(2 * i)
|
|
97
|
+
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
def __runSelectSQL(self, query):
|
|
101
|
+
""" """
|
|
102
|
+
rows = ()
|
|
103
|
+
try:
|
|
104
|
+
self.__dbcon.commit()
|
|
105
|
+
curs = self.__dbcon.cursor(MySQLdb.cursors.DictCursor)
|
|
106
|
+
curs.execute(query)
|
|
107
|
+
rows = curs.fetchall()
|
|
108
|
+
except MySQLdb.Error as e:
|
|
109
|
+
self.__dbState = e.args[0]
|
|
110
|
+
self.__lfh.write("Database error %s: %s\n" % (e.args[0], e.args[1]))
|
|
111
|
+
|
|
112
|
+
return rows
|
|
113
|
+
|
|
114
|
+
def __runUpdateSQL(self, query):
|
|
115
|
+
""" """
|
|
116
|
+
try:
|
|
117
|
+
curs = self.__dbcon.cursor()
|
|
118
|
+
curs.execute("set autocommit=0")
|
|
119
|
+
_nrows = curs.execute(query) # noqa: F841
|
|
120
|
+
self.__dbcon.commit()
|
|
121
|
+
curs.execute("set autocommit=1")
|
|
122
|
+
curs.close()
|
|
123
|
+
return "OK"
|
|
124
|
+
except MySQLdb.Error as e:
|
|
125
|
+
self.__dbcon.rollback()
|
|
126
|
+
self.__dbState = e.args[0]
|
|
127
|
+
self.__lfh.write("Database error %s: %s\n" % (e.args[0], e.args[1]))
|
|
128
|
+
#
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
def setSchemaMap(self, schemaMap):
|
|
132
|
+
""" """
|
|
133
|
+
self.__schemaMap = schemaMap
|
|
134
|
+
|
|
135
|
+
def runSelectSQL(self, sql):
|
|
136
|
+
"""method to run a query"""
|
|
137
|
+
for retry in range(1, self.__Nretry):
|
|
138
|
+
ret = self.__runSelectSQL(sql)
|
|
139
|
+
if ret is None:
|
|
140
|
+
if self.__dbState > 0:
|
|
141
|
+
time.sleep(retry * 2)
|
|
142
|
+
if not self.__reConnect():
|
|
143
|
+
return None
|
|
144
|
+
else:
|
|
145
|
+
return None
|
|
146
|
+
#
|
|
147
|
+
else:
|
|
148
|
+
return ret
|
|
149
|
+
#
|
|
150
|
+
#
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
def runUpdateSQL(self, sql):
|
|
154
|
+
"""method to run a query"""
|
|
155
|
+
for retry in range(1, self.__Nretry):
|
|
156
|
+
ret = self.__runUpdateSQL(sql)
|
|
157
|
+
if ret is None:
|
|
158
|
+
if self.__dbState > 0:
|
|
159
|
+
time.sleep(retry * 2)
|
|
160
|
+
if not self.__reConnect():
|
|
161
|
+
return None
|
|
162
|
+
else:
|
|
163
|
+
return None
|
|
164
|
+
#
|
|
165
|
+
else:
|
|
166
|
+
return ret
|
|
167
|
+
#
|
|
168
|
+
#
|
|
169
|
+
return None
|
|
170
|
+
|
|
171
|
+
def runUpdate(self, table=None, where=None, data=None):
|
|
172
|
+
if not table:
|
|
173
|
+
return None
|
|
174
|
+
#
|
|
175
|
+
if (not where) and (not data):
|
|
176
|
+
return None
|
|
177
|
+
#
|
|
178
|
+
rowExists = False
|
|
179
|
+
if where:
|
|
180
|
+
sql = (
|
|
181
|
+
"select * from " # noqa: S608
|
|
182
|
+
+ str(table)
|
|
183
|
+
+ " where "
|
|
184
|
+
+ " and ".join(["%s = '%s'" % (k, v.replace("'", "\\'")) for k, v in where.items()])
|
|
185
|
+
) # noqa: S608
|
|
186
|
+
rows = self.runSelectSQL(sql)
|
|
187
|
+
if rows and len(rows) > 0:
|
|
188
|
+
rowExists = True
|
|
189
|
+
#
|
|
190
|
+
#
|
|
191
|
+
if rowExists and (not data):
|
|
192
|
+
return "OK"
|
|
193
|
+
#
|
|
194
|
+
if rowExists:
|
|
195
|
+
sql = (
|
|
196
|
+
"update " # noqa: S608
|
|
197
|
+
+ str(table)
|
|
198
|
+
+ " set "
|
|
199
|
+
+ ",".join(["%s = '%s'" % (k, v.replace("'", "\\'")) for k, v in data.items()])
|
|
200
|
+
) # noqa: S608
|
|
201
|
+
if where:
|
|
202
|
+
sql += " where " + " and ".join(["%s = '%s'" % (k, v.replace("'", "\\'")) for k, v in where.items()])
|
|
203
|
+
#
|
|
204
|
+
else:
|
|
205
|
+
sql = "insert into " + str(table) + " (" + ",".join(["%s" % (k) for k, v in where.items()])
|
|
206
|
+
if data:
|
|
207
|
+
sql += "," + ",".join(["%s" % (k) for k, v in data.items()])
|
|
208
|
+
#
|
|
209
|
+
sql += ") values (" + ",".join(["'%s'" % (v.replace("'", "\\'")) for k, v in where.items()])
|
|
210
|
+
if data:
|
|
211
|
+
sql += "," + ",".join(["'%s'" % (v.replace("'", "\\'")) for k, v in data.items()])
|
|
212
|
+
#
|
|
213
|
+
sql += ")"
|
|
214
|
+
#
|
|
215
|
+
return self.runUpdateSQL(sql)
|
|
216
|
+
|
|
217
|
+
def runUpdateSQLwithKey(self, key=None, parameter=()):
|
|
218
|
+
""" """
|
|
219
|
+
if not key or not self.__schemaMap or (key not in self.__schemaMap):
|
|
220
|
+
return None
|
|
221
|
+
#
|
|
222
|
+
sql = self.__schemaMap[key]
|
|
223
|
+
if parameter:
|
|
224
|
+
sql = self.__schemaMap[key] % parameter
|
|
225
|
+
#
|
|
226
|
+
return self.runUpdateSQL(sql)
|
|
227
|
+
|
|
228
|
+
def selectData(self, key=None, parameter=()):
|
|
229
|
+
""" """
|
|
230
|
+
if key is None or not self.__schemaMap or (key not in self.__schemaMap):
|
|
231
|
+
return None
|
|
232
|
+
#
|
|
233
|
+
sql = self.__schemaMap[key]
|
|
234
|
+
if parameter:
|
|
235
|
+
sql = self.__schemaMap[key] % parameter
|
|
236
|
+
#
|
|
237
|
+
return self.runSelectSQL(sql)
|