modulitiz-micro 2.43.0__py311-none-any.whl → 2.44.1__py311-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.
- modulitiz_micro/ModuloSeriale.py +70 -70
- modulitiz_micro/ModuloTarghe.py +47 -47
- modulitiz_micro/database/AbstractDatabaseService.py +13 -13
- modulitiz_micro/database/AbstractSql.py +69 -69
- modulitiz_micro/database/ModuloSqlOracle.py +19 -19
- modulitiz_micro/database/ModuloSqlServer.py +43 -43
- modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -6
- modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -114
- modulitiz_micro/database/mysql/ModuloMysql.py +163 -163
- modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -47
- modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -6
- modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -114
- modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -82
- modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -7
- modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -7
- modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -8
- modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -7
- modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -7
- modulitiz_micro/files/cache/DatabaseCache.py +91 -91
- modulitiz_micro/files/cache/decorators/cacheRam.py +26 -26
- modulitiz_micro/files/git/ModuloGit.py +28 -28
- modulitiz_micro/files/git/decorators/catchAndRaiseGitExceptions.py +19 -19
- modulitiz_micro/files/git/exceptions/EccezioneGit.py +7 -7
- modulitiz_micro/gestionedom/GestioneDom.py +44 -44
- modulitiz_micro/iot/ModuleIotDevice.py +62 -62
- modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -7
- modulitiz_micro/keylogger/ModuloKeylogger.py +73 -73
- modulitiz_micro/rete/ModuloNetworking.py +72 -72
- modulitiz_micro/rete/ModuloOpenVpn.py +15 -15
- modulitiz_micro/rete/email/EmailBean.py +5 -5
- modulitiz_micro/rete/email/ModuloEmail.py +90 -90
- modulitiz_micro/rete/http/ModuloHttp.py +119 -119
- modulitiz_micro/rete/http/ModuloHttpConnectionSafe.py +91 -91
- modulitiz_micro/rete/http/ModuloHttpUtils.py +69 -69
- modulitiz_micro/rete/http/beans/HttpResponseBean.py +5 -5
- modulitiz_micro/rete/http/decorators/catchAndRaiseHttpExceptions.py +22 -22
- modulitiz_micro/rete/http/huawei/fusionsolar/ModuleHuaweiFusionSolar.py +84 -0
- modulitiz_micro/rete/http/huawei/fusionsolar/beans/TokenBean.py +28 -0
- modulitiz_micro/rete/http/huawei/fusionsolar/beans/device/DeviceBean.py +6 -0
- modulitiz_micro/rete/http/huawei/fusionsolar/beans/device/DeviceDataBattery.py +22 -0
- modulitiz_micro/rete/http/huawei/fusionsolar/beans/device/DeviceDataPowerSensor.py +49 -0
- modulitiz_micro/rete/http/huawei/fusionsolar/beans/device/DeviceDataResidentialInverter.py +46 -0
- modulitiz_micro/rete/http/huawei/fusionsolar/enums/DevTypeIdEnum.py +21 -0
- modulitiz_micro/rete/http/huawei/fusionsolar/exceptions/ExceptionTooManyLogins.py +7 -0
- modulitiz_micro/rete/http/huawei/fusionsolar/service/AbstractHuaweiFusionSolar.py +71 -0
- modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -73
- modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -8
- modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -35
- modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -267
- modulitiz_micro/rete/ssl/ModuloSsl.py +56 -56
- modulitiz_micro/sistema/ModuloEnvVars.py +34 -34
- modulitiz_micro/sistema/ModuloSystemPipe.py +67 -67
- modulitiz_micro/social/telegram/AbstractModuloTelegram.py +53 -53
- modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -26
- modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -15
- modulitiz_micro/util/scheduler/ModuleScheduler.py +26 -26
- modulitiz_micro/weather/AbstractModuleWeather.py +31 -0
- modulitiz_micro/weather/ModuleWeather.py +62 -0
- {modulitiz_micro-2.43.0.dist-info → modulitiz_micro-2.44.1.dist-info}/METADATA +59 -59
- modulitiz_micro-2.44.1.dist-info/RECORD +66 -0
- {modulitiz_micro-2.43.0.dist-info → modulitiz_micro-2.44.1.dist-info}/licenses/LICENSE +21 -21
- modulitiz_micro/ModuloMeteo.py +0 -72
- modulitiz_micro-2.43.0.dist-info/RECORD +0 -56
- {modulitiz_micro-2.43.0.dist-info → modulitiz_micro-2.44.1.dist-info}/WHEEL +0 -0
- {modulitiz_micro-2.43.0.dist-info → modulitiz_micro-2.44.1.dist-info}/top_level.txt +0 -0
@@ -1,114 +1,114 @@
|
|
1
|
-
from abc import abstractmethod
|
2
|
-
|
3
|
-
from modulitiz_nano.ModuloStringhe import ModuloStringhe
|
4
|
-
from modulitiz_micro.database.mysql.ModuloMysql import ModuloMysql
|
5
|
-
|
6
|
-
|
7
|
-
class AbstractBasicMysql(ModuloMysql):
|
8
|
-
|
9
|
-
def __init__(self,*args,**kwargs):
|
10
|
-
super().__init__(*args,**kwargs)
|
11
|
-
|
12
|
-
def initDdlBasicTables(self):
|
13
|
-
if not self.isDbNew:
|
14
|
-
return
|
15
|
-
sqlStr=ModuloStringhe.normalizzaEol(self.schemaBasicTables())
|
16
|
-
for results in self.executeScript(sqlStr):
|
17
|
-
yield results
|
18
|
-
sqlInsertBasicTables=self.insertBasicTables()
|
19
|
-
if not ModuloStringhe.isEmpty(sqlInsertBasicTables):
|
20
|
-
sqlInsertBasicTables=ModuloStringhe.normalizzaEol(sqlInsertBasicTables)
|
21
|
-
for results in self.executeScript(sqlInsertBasicTables):
|
22
|
-
yield results
|
23
|
-
self.commit()
|
24
|
-
|
25
|
-
def schemaBasicTables(self):
|
26
|
-
return """
|
27
|
-
|
28
|
-
CREATE TABLE tb_params(
|
29
|
-
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
|
30
|
-
type1 CHAR(30) NOT NULL,
|
31
|
-
key1 CHAR(30) NOT NULL,
|
32
|
-
desc1 CHAR(100) NOT NULL,
|
33
|
-
enabled BOOLEAN NOT NULL,
|
34
|
-
lang_code CHAR(2) NULL,
|
35
|
-
data_insert DATETIME NOT NULL
|
36
|
-
)"""+self.TABLE_OPTIONS+""";
|
37
|
-
CREATE UNIQUE INDEX PARAMS__UK1 ON tb_params(type1,key1,lang_code);
|
38
|
-
|
39
|
-
"""
|
40
|
-
|
41
|
-
@abstractmethod
|
42
|
-
def insertBasicTables(self):
|
43
|
-
"""
|
44
|
-
Inserire le istruzioni sql che vanno eseguite alla fine di tutto
|
45
|
-
"""
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
#############################################################################################################################
|
50
|
-
#############################################################################################################################
|
51
|
-
#############################################################################################################################
|
52
|
-
def selectParamDescByEntries(self,paramType:str,paramKey:str|None)->str|None:
|
53
|
-
cursoreDb=self.selectParamByEntries(paramType, paramKey, None, True)
|
54
|
-
results=self.fetchAll(cursoreDb)
|
55
|
-
if len(results)==0:
|
56
|
-
return None
|
57
|
-
result=results[0]
|
58
|
-
return result['desc1']
|
59
|
-
|
60
|
-
def selectParamByEntries(self,paramType:str,paramKey:str|None,langCode:str|None,enabled:bool|None):
|
61
|
-
addParamKey=ModuloStringhe.isEmpty(paramKey) is False
|
62
|
-
addLangCode=ModuloStringhe.isEmpty(langCode) is False
|
63
|
-
addEnabled=enabled is not None
|
64
|
-
|
65
|
-
sql="""
|
66
|
-
SELECT *
|
67
|
-
FROM tb_params
|
68
|
-
WHERE type1=%(paramType)s
|
69
|
-
"""+("AND key1=%(paramKey)s" if addParamKey is True else "")+"""
|
70
|
-
"""+("AND langCode=%(langCode)s" if addLangCode is True else "")+"""
|
71
|
-
"""+("AND enabled=%(enabled)s" if addEnabled is True else "")+"""
|
72
|
-
;
|
73
|
-
"""
|
74
|
-
params= {'paramType': paramType}
|
75
|
-
if addParamKey is True:
|
76
|
-
params['paramKey']=paramKey
|
77
|
-
if addLangCode is True:
|
78
|
-
params['langCode']=langCode
|
79
|
-
if addEnabled is True:
|
80
|
-
params['enabled']=enabled
|
81
|
-
|
82
|
-
cursoreDb=self.initCursor()
|
83
|
-
with self.lock:
|
84
|
-
cursoreDb.execute(sql,params)
|
85
|
-
return cursoreDb
|
86
|
-
|
87
|
-
|
88
|
-
def updateParamDesc(self,paramType:str,paramKey:str|None,newDesc:str|None):
|
89
|
-
addParamKey=ModuloStringhe.isEmpty(paramKey) is False
|
90
|
-
addNewDesc=ModuloStringhe.isEmpty(newDesc) is False
|
91
|
-
|
92
|
-
sqlSet=[]
|
93
|
-
if addNewDesc is True:
|
94
|
-
sqlSet.append("desc1=%(newDesc)s")
|
95
|
-
sqlSet=", ".join(sqlSet)
|
96
|
-
|
97
|
-
sql="""
|
98
|
-
UPDATE tb_params
|
99
|
-
SET """+sqlSet+"""
|
100
|
-
WHERE type1=%(paramType)s
|
101
|
-
"""+("AND key1=%(paramKey)s" if addParamKey is True else "")+"""
|
102
|
-
;
|
103
|
-
"""
|
104
|
-
params={}
|
105
|
-
if addNewDesc is True:
|
106
|
-
params['newDesc']=newDesc
|
107
|
-
params['paramType']=paramType
|
108
|
-
if addParamKey is True:
|
109
|
-
params['paramKey']=paramKey
|
110
|
-
cursoreDb=self.initCursor()
|
111
|
-
with self.lock:
|
112
|
-
cursoreDb.execute(sql,params)
|
113
|
-
return cursoreDb
|
114
|
-
|
1
|
+
from abc import abstractmethod
|
2
|
+
|
3
|
+
from modulitiz_nano.ModuloStringhe import ModuloStringhe
|
4
|
+
from modulitiz_micro.database.mysql.ModuloMysql import ModuloMysql
|
5
|
+
|
6
|
+
|
7
|
+
class AbstractBasicMysql(ModuloMysql):
|
8
|
+
|
9
|
+
def __init__(self,*args,**kwargs):
|
10
|
+
super().__init__(*args,**kwargs)
|
11
|
+
|
12
|
+
def initDdlBasicTables(self):
|
13
|
+
if not self.isDbNew:
|
14
|
+
return
|
15
|
+
sqlStr=ModuloStringhe.normalizzaEol(self.schemaBasicTables())
|
16
|
+
for results in self.executeScript(sqlStr):
|
17
|
+
yield results
|
18
|
+
sqlInsertBasicTables=self.insertBasicTables()
|
19
|
+
if not ModuloStringhe.isEmpty(sqlInsertBasicTables):
|
20
|
+
sqlInsertBasicTables=ModuloStringhe.normalizzaEol(sqlInsertBasicTables)
|
21
|
+
for results in self.executeScript(sqlInsertBasicTables):
|
22
|
+
yield results
|
23
|
+
self.commit()
|
24
|
+
|
25
|
+
def schemaBasicTables(self):
|
26
|
+
return """
|
27
|
+
|
28
|
+
CREATE TABLE tb_params(
|
29
|
+
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
|
30
|
+
type1 CHAR(30) NOT NULL,
|
31
|
+
key1 CHAR(30) NOT NULL,
|
32
|
+
desc1 CHAR(100) NOT NULL,
|
33
|
+
enabled BOOLEAN NOT NULL,
|
34
|
+
lang_code CHAR(2) NULL,
|
35
|
+
data_insert DATETIME NOT NULL
|
36
|
+
)"""+self.TABLE_OPTIONS+""";
|
37
|
+
CREATE UNIQUE INDEX PARAMS__UK1 ON tb_params(type1,key1,lang_code);
|
38
|
+
|
39
|
+
"""
|
40
|
+
|
41
|
+
@abstractmethod
|
42
|
+
def insertBasicTables(self):
|
43
|
+
"""
|
44
|
+
Inserire le istruzioni sql che vanno eseguite alla fine di tutto
|
45
|
+
"""
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
#############################################################################################################################
|
50
|
+
#############################################################################################################################
|
51
|
+
#############################################################################################################################
|
52
|
+
def selectParamDescByEntries(self,paramType:str,paramKey:str|None)->str|None:
|
53
|
+
cursoreDb=self.selectParamByEntries(paramType, paramKey, None, True)
|
54
|
+
results=self.fetchAll(cursoreDb)
|
55
|
+
if len(results)==0:
|
56
|
+
return None
|
57
|
+
result=results[0]
|
58
|
+
return result['desc1']
|
59
|
+
|
60
|
+
def selectParamByEntries(self,paramType:str,paramKey:str|None,langCode:str|None,enabled:bool|None):
|
61
|
+
addParamKey=ModuloStringhe.isEmpty(paramKey) is False
|
62
|
+
addLangCode=ModuloStringhe.isEmpty(langCode) is False
|
63
|
+
addEnabled=enabled is not None
|
64
|
+
|
65
|
+
sql="""
|
66
|
+
SELECT *
|
67
|
+
FROM tb_params
|
68
|
+
WHERE type1=%(paramType)s
|
69
|
+
"""+("AND key1=%(paramKey)s" if addParamKey is True else "")+"""
|
70
|
+
"""+("AND langCode=%(langCode)s" if addLangCode is True else "")+"""
|
71
|
+
"""+("AND enabled=%(enabled)s" if addEnabled is True else "")+"""
|
72
|
+
;
|
73
|
+
"""
|
74
|
+
params= {'paramType': paramType}
|
75
|
+
if addParamKey is True:
|
76
|
+
params['paramKey']=paramKey
|
77
|
+
if addLangCode is True:
|
78
|
+
params['langCode']=langCode
|
79
|
+
if addEnabled is True:
|
80
|
+
params['enabled']=enabled
|
81
|
+
|
82
|
+
cursoreDb=self.initCursor()
|
83
|
+
with self.lock:
|
84
|
+
cursoreDb.execute(sql,params)
|
85
|
+
return cursoreDb
|
86
|
+
|
87
|
+
|
88
|
+
def updateParamDesc(self,paramType:str,paramKey:str|None,newDesc:str|None):
|
89
|
+
addParamKey=ModuloStringhe.isEmpty(paramKey) is False
|
90
|
+
addNewDesc=ModuloStringhe.isEmpty(newDesc) is False
|
91
|
+
|
92
|
+
sqlSet=[]
|
93
|
+
if addNewDesc is True:
|
94
|
+
sqlSet.append("desc1=%(newDesc)s")
|
95
|
+
sqlSet=", ".join(sqlSet)
|
96
|
+
|
97
|
+
sql="""
|
98
|
+
UPDATE tb_params
|
99
|
+
SET """+sqlSet+"""
|
100
|
+
WHERE type1=%(paramType)s
|
101
|
+
"""+("AND key1=%(paramKey)s" if addParamKey is True else "")+"""
|
102
|
+
;
|
103
|
+
"""
|
104
|
+
params={}
|
105
|
+
if addNewDesc is True:
|
106
|
+
params['newDesc']=newDesc
|
107
|
+
params['paramType']=paramType
|
108
|
+
if addParamKey is True:
|
109
|
+
params['paramKey']=paramKey
|
110
|
+
cursoreDb=self.initCursor()
|
111
|
+
with self.lock:
|
112
|
+
cursoreDb.execute(sql,params)
|
113
|
+
return cursoreDb
|
114
|
+
|
@@ -1,163 +1,163 @@
|
|
1
|
-
from abc import abstractmethod
|
2
|
-
|
3
|
-
import mysql.connector
|
4
|
-
|
5
|
-
from modulitiz_nano.ModuloListe import ModuloListe
|
6
|
-
from modulitiz_nano.ModuloStringhe import ModuloStringhe
|
7
|
-
from modulitiz_micro.database.AbstractSql import AbstractSql
|
8
|
-
from modulitiz_micro.database.eccezioni.EccezioneDbNoData import EccezioneDbNoData
|
9
|
-
from modulitiz_micro.database.mysql.MysqlCommonConverter import MysqlCommonConverter
|
10
|
-
from modulitiz_nano.eccezioni.EccezioneRuntime import EccezioneRuntime
|
11
|
-
from modulitiz_nano.files.ModuloFiles import ModuloFiles
|
12
|
-
from modulitiz_nano.files.ModuloLogging import ModuloLogging
|
13
|
-
from modulitiz_nano.sistema.ModuloSystem import ModuloSystem
|
14
|
-
|
15
|
-
|
16
|
-
class ModuloMysql(AbstractSql):
|
17
|
-
"""
|
18
|
-
select
|
19
|
-
count
|
20
|
-
insert
|
21
|
-
update
|
22
|
-
delete
|
23
|
-
"""
|
24
|
-
|
25
|
-
DATE_TIME_NOW="NOW()"
|
26
|
-
|
27
|
-
DEFAULT_PORT=3306
|
28
|
-
|
29
|
-
|
30
|
-
def __init__(self,host: str,porta: int|None,user: str,password: str,nomeDb: str,isDebug: bool):
|
31
|
-
super().__init__()
|
32
|
-
self.nomeDb=nomeDb
|
33
|
-
if porta is None:
|
34
|
-
porta=self.DEFAULT_PORT
|
35
|
-
# apro la connessione col server
|
36
|
-
self.connDb=mysql.connector.connect(user=user,password=password,host=host,port=porta,
|
37
|
-
converter_class=MysqlCommonConverter)
|
38
|
-
self.initCursor()
|
39
|
-
self.TABLE_OPTIONS=self.getTableOptions(isDebug)
|
40
|
-
self.isDbNew=None
|
41
|
-
|
42
|
-
@abstractmethod
|
43
|
-
def schema(self):
|
44
|
-
"""
|
45
|
-
Insert here sql instructions containing table definitions (DDL)
|
46
|
-
"""
|
47
|
-
|
48
|
-
def initDdl(self):
|
49
|
-
#scelgo il db
|
50
|
-
try:
|
51
|
-
self.connDb.cmd_init_db(self.nomeDb)
|
52
|
-
self.isDbNew=False
|
53
|
-
except mysql.connector.ProgrammingError:
|
54
|
-
sqlCreaDb="CREATE DATABASE %s;"%(self.nomeDb,)
|
55
|
-
with self.initCursor() as cursoreDb:
|
56
|
-
with self.lock:
|
57
|
-
cursoreDb.execute(sqlCreaDb)
|
58
|
-
self.connDb.cmd_init_db(self.nomeDb)
|
59
|
-
self.isDbNew=True
|
60
|
-
#se il db non esisteva creo le tabelle
|
61
|
-
if self.isDbNew:
|
62
|
-
sqlStr=ModuloStringhe.normalizzaEol(self.schema())
|
63
|
-
for results in self.executeScript(sqlStr):
|
64
|
-
yield results
|
65
|
-
|
66
|
-
@staticmethod
|
67
|
-
def getLastIdInserted(cursoreDb):
|
68
|
-
return cursoreDb.lastrowid
|
69
|
-
|
70
|
-
def selectNow(self):
|
71
|
-
"""
|
72
|
-
Returns current db date and time.
|
73
|
-
"""
|
74
|
-
sql="SELECT {};".format(self.DATE_TIME_NOW)
|
75
|
-
with self.initCursor() as cursoreDb:
|
76
|
-
with self.lock:
|
77
|
-
cursoreDb.execute(sql,{})
|
78
|
-
output=self.fetchOne(cursoreDb)
|
79
|
-
return output
|
80
|
-
|
81
|
-
def executeScript(self,sqlStr:str):
|
82
|
-
sqlCmds=sqlStr.split(";")
|
83
|
-
sqlCmds=ModuloListe.eliminaElementiVuoti(sqlCmds)
|
84
|
-
numCmds=len(sqlCmds)
|
85
|
-
cursoreDb=self.initCursor()
|
86
|
-
for index,sqlCmd in enumerate(sqlCmds):
|
87
|
-
sqlCmd=sqlCmd.strip()
|
88
|
-
try:
|
89
|
-
if sqlCmd!="":
|
90
|
-
with self.lock:
|
91
|
-
cursoreDb.execute(sqlCmd)
|
92
|
-
yield index,numCmds
|
93
|
-
except Exception as ex:
|
94
|
-
raise EccezioneRuntime(sqlCmd+"\n\n"+ModuloLogging.exceptionToString(ex))
|
95
|
-
|
96
|
-
def fetchAll(self,cursoreDb)->list:
|
97
|
-
with cursoreDb:
|
98
|
-
if cursoreDb.description is None:
|
99
|
-
raise EccezioneDbNoData()
|
100
|
-
descriptions=cursoreDb.description
|
101
|
-
with self.lock:
|
102
|
-
rows=cursoreDb.fetchall()
|
103
|
-
self.commitNoLock() # mysql mette in cache i risultati, lo risolvo così, è un bug loro...
|
104
|
-
columns = [col[0] for col in descriptions]
|
105
|
-
rows = [dict(zip(columns, row)) for row in rows]
|
106
|
-
return rows
|
107
|
-
|
108
|
-
@classmethod
|
109
|
-
def backup(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
110
|
-
ignoreTables:list|tuple|None)->list:
|
111
|
-
output=[
|
112
|
-
cls.backupDdl(percorsoCartella,user,password,dbName,ignoreTables),
|
113
|
-
cls.backupData(percorsoCartella,user,password,dbName,ignoreTables)
|
114
|
-
]
|
115
|
-
return output
|
116
|
-
|
117
|
-
@classmethod
|
118
|
-
def backupDdl(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
119
|
-
ignoreTables:list|tuple|None)->str:
|
120
|
-
return cls.__backup(percorsoCartella,user,password,dbName,ignoreTables,True,False)
|
121
|
-
@classmethod
|
122
|
-
def backupData(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
123
|
-
ignoreTables:list|tuple|None)->str:
|
124
|
-
return cls.__backup(percorsoCartella,user,password,dbName,ignoreTables,False,True)
|
125
|
-
|
126
|
-
@staticmethod
|
127
|
-
def __backup(percorsoCartella:str,user:str,password:str,dbName:str,
|
128
|
-
ignoreTables:list|tuple|None,onlyDdl:bool,onlyData:bool)->str:
|
129
|
-
if onlyDdl and onlyData:
|
130
|
-
raise EccezioneRuntime("valorizzare solo un'opzione alla volta")
|
131
|
-
cmdIgnoreTables=""
|
132
|
-
if ignoreTables is not None:
|
133
|
-
cmdIgnoreTables=" ".join(["--ignore-table=%s.%s"%(dbName,x) for x in ignoreTables])
|
134
|
-
nomefileSuffix=""
|
135
|
-
cmdOptions=""
|
136
|
-
if onlyDdl:
|
137
|
-
nomefileSuffix="_ddl"
|
138
|
-
cmdOptions="--no-data "+cmdIgnoreTables
|
139
|
-
elif onlyData:
|
140
|
-
nomefileSuffix="_data"
|
141
|
-
cmdOptions="--order-by-primary --no-create-info --quick "+cmdIgnoreTables
|
142
|
-
nomefileOutput=dbName+nomefileSuffix+".sql"
|
143
|
-
percorsoFileBackup=ModuloFiles.pathJoin(percorsoCartella,nomefileOutput)
|
144
|
-
cmd=r'mysqldump -u {} -p{} --databases {} --skip-add-drop-table --skip-comments {} -r "{}"'.format(user,password,dbName,cmdOptions,percorsoFileBackup)
|
145
|
-
output=ModuloSystem.systemCallReturnOutput(cmd,None).strip()
|
146
|
-
if not ModuloStringhe.isEmpty(output):
|
147
|
-
raise EccezioneRuntime(output)
|
148
|
-
return percorsoFileBackup
|
149
|
-
|
150
|
-
@staticmethod
|
151
|
-
def getTableOptions(isDebug: bool) -> str:
|
152
|
-
return "ENGINE=%s DEFAULT CHARSET=utf8"%("InnoDB" if not isDebug else "MEMORY",)
|
153
|
-
|
154
|
-
def paginazione(firstResult:int,numResults:int)->str:
|
155
|
-
sql=("LIMIT "+str(numResults) if numResults is not None else "")+\
|
156
|
-
(" OFFSET "+str(firstResult) if firstResult is not None else "")
|
157
|
-
return sql
|
158
|
-
|
159
|
-
def add_param_list(lista:list,prefix:str)->dict:
|
160
|
-
params={}
|
161
|
-
for index,elem in enumerate(lista):
|
162
|
-
params[prefix+str(index)]=elem
|
163
|
-
return params
|
1
|
+
from abc import abstractmethod
|
2
|
+
|
3
|
+
import mysql.connector
|
4
|
+
|
5
|
+
from modulitiz_nano.ModuloListe import ModuloListe
|
6
|
+
from modulitiz_nano.ModuloStringhe import ModuloStringhe
|
7
|
+
from modulitiz_micro.database.AbstractSql import AbstractSql
|
8
|
+
from modulitiz_micro.database.eccezioni.EccezioneDbNoData import EccezioneDbNoData
|
9
|
+
from modulitiz_micro.database.mysql.MysqlCommonConverter import MysqlCommonConverter
|
10
|
+
from modulitiz_nano.eccezioni.EccezioneRuntime import EccezioneRuntime
|
11
|
+
from modulitiz_nano.files.ModuloFiles import ModuloFiles
|
12
|
+
from modulitiz_nano.files.ModuloLogging import ModuloLogging
|
13
|
+
from modulitiz_nano.sistema.ModuloSystem import ModuloSystem
|
14
|
+
|
15
|
+
|
16
|
+
class ModuloMysql(AbstractSql):
|
17
|
+
"""
|
18
|
+
select
|
19
|
+
count
|
20
|
+
insert
|
21
|
+
update
|
22
|
+
delete
|
23
|
+
"""
|
24
|
+
|
25
|
+
DATE_TIME_NOW="NOW()"
|
26
|
+
|
27
|
+
DEFAULT_PORT=3306
|
28
|
+
|
29
|
+
|
30
|
+
def __init__(self,host: str,porta: int|None,user: str,password: str,nomeDb: str,isDebug: bool):
|
31
|
+
super().__init__()
|
32
|
+
self.nomeDb=nomeDb
|
33
|
+
if porta is None:
|
34
|
+
porta=self.DEFAULT_PORT
|
35
|
+
# apro la connessione col server
|
36
|
+
self.connDb=mysql.connector.connect(user=user,password=password,host=host,port=porta,
|
37
|
+
converter_class=MysqlCommonConverter)
|
38
|
+
self.initCursor()
|
39
|
+
self.TABLE_OPTIONS=self.getTableOptions(isDebug)
|
40
|
+
self.isDbNew=None
|
41
|
+
|
42
|
+
@abstractmethod
|
43
|
+
def schema(self):
|
44
|
+
"""
|
45
|
+
Insert here sql instructions containing table definitions (DDL)
|
46
|
+
"""
|
47
|
+
|
48
|
+
def initDdl(self):
|
49
|
+
#scelgo il db
|
50
|
+
try:
|
51
|
+
self.connDb.cmd_init_db(self.nomeDb)
|
52
|
+
self.isDbNew=False
|
53
|
+
except mysql.connector.ProgrammingError:
|
54
|
+
sqlCreaDb="CREATE DATABASE %s;"%(self.nomeDb,)
|
55
|
+
with self.initCursor() as cursoreDb:
|
56
|
+
with self.lock:
|
57
|
+
cursoreDb.execute(sqlCreaDb)
|
58
|
+
self.connDb.cmd_init_db(self.nomeDb)
|
59
|
+
self.isDbNew=True
|
60
|
+
#se il db non esisteva creo le tabelle
|
61
|
+
if self.isDbNew:
|
62
|
+
sqlStr=ModuloStringhe.normalizzaEol(self.schema())
|
63
|
+
for results in self.executeScript(sqlStr):
|
64
|
+
yield results
|
65
|
+
|
66
|
+
@staticmethod
|
67
|
+
def getLastIdInserted(cursoreDb):
|
68
|
+
return cursoreDb.lastrowid
|
69
|
+
|
70
|
+
def selectNow(self):
|
71
|
+
"""
|
72
|
+
Returns current db date and time.
|
73
|
+
"""
|
74
|
+
sql="SELECT {};".format(self.DATE_TIME_NOW)
|
75
|
+
with self.initCursor() as cursoreDb:
|
76
|
+
with self.lock:
|
77
|
+
cursoreDb.execute(sql,{})
|
78
|
+
output=self.fetchOne(cursoreDb)
|
79
|
+
return output
|
80
|
+
|
81
|
+
def executeScript(self,sqlStr:str):
|
82
|
+
sqlCmds=sqlStr.split(";")
|
83
|
+
sqlCmds=ModuloListe.eliminaElementiVuoti(sqlCmds)
|
84
|
+
numCmds=len(sqlCmds)
|
85
|
+
cursoreDb=self.initCursor()
|
86
|
+
for index,sqlCmd in enumerate(sqlCmds):
|
87
|
+
sqlCmd=sqlCmd.strip()
|
88
|
+
try:
|
89
|
+
if sqlCmd!="":
|
90
|
+
with self.lock:
|
91
|
+
cursoreDb.execute(sqlCmd)
|
92
|
+
yield index,numCmds
|
93
|
+
except Exception as ex:
|
94
|
+
raise EccezioneRuntime(sqlCmd+"\n\n"+ModuloLogging.exceptionToString(ex))
|
95
|
+
|
96
|
+
def fetchAll(self,cursoreDb)->list:
|
97
|
+
with cursoreDb:
|
98
|
+
if cursoreDb.description is None:
|
99
|
+
raise EccezioneDbNoData()
|
100
|
+
descriptions=cursoreDb.description
|
101
|
+
with self.lock:
|
102
|
+
rows=cursoreDb.fetchall()
|
103
|
+
self.commitNoLock() # mysql mette in cache i risultati, lo risolvo così, è un bug loro...
|
104
|
+
columns = [col[0] for col in descriptions]
|
105
|
+
rows = [dict(zip(columns, row)) for row in rows]
|
106
|
+
return rows
|
107
|
+
|
108
|
+
@classmethod
|
109
|
+
def backup(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
110
|
+
ignoreTables:list|tuple|None)->list:
|
111
|
+
output=[
|
112
|
+
cls.backupDdl(percorsoCartella,user,password,dbName,ignoreTables),
|
113
|
+
cls.backupData(percorsoCartella,user,password,dbName,ignoreTables)
|
114
|
+
]
|
115
|
+
return output
|
116
|
+
|
117
|
+
@classmethod
|
118
|
+
def backupDdl(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
119
|
+
ignoreTables:list|tuple|None)->str:
|
120
|
+
return cls.__backup(percorsoCartella,user,password,dbName,ignoreTables,True,False)
|
121
|
+
@classmethod
|
122
|
+
def backupData(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
123
|
+
ignoreTables:list|tuple|None)->str:
|
124
|
+
return cls.__backup(percorsoCartella,user,password,dbName,ignoreTables,False,True)
|
125
|
+
|
126
|
+
@staticmethod
|
127
|
+
def __backup(percorsoCartella:str,user:str,password:str,dbName:str,
|
128
|
+
ignoreTables:list|tuple|None,onlyDdl:bool,onlyData:bool)->str:
|
129
|
+
if onlyDdl and onlyData:
|
130
|
+
raise EccezioneRuntime("valorizzare solo un'opzione alla volta")
|
131
|
+
cmdIgnoreTables=""
|
132
|
+
if ignoreTables is not None:
|
133
|
+
cmdIgnoreTables=" ".join(["--ignore-table=%s.%s"%(dbName,x) for x in ignoreTables])
|
134
|
+
nomefileSuffix=""
|
135
|
+
cmdOptions=""
|
136
|
+
if onlyDdl:
|
137
|
+
nomefileSuffix="_ddl"
|
138
|
+
cmdOptions="--no-data "+cmdIgnoreTables
|
139
|
+
elif onlyData:
|
140
|
+
nomefileSuffix="_data"
|
141
|
+
cmdOptions="--order-by-primary --no-create-info --quick "+cmdIgnoreTables
|
142
|
+
nomefileOutput=dbName+nomefileSuffix+".sql"
|
143
|
+
percorsoFileBackup=ModuloFiles.pathJoin(percorsoCartella,nomefileOutput)
|
144
|
+
cmd=r'mysqldump -u {} -p{} --databases {} --skip-add-drop-table --skip-comments {} -r "{}"'.format(user,password,dbName,cmdOptions,percorsoFileBackup)
|
145
|
+
output=ModuloSystem.systemCallReturnOutput(cmd,None).strip()
|
146
|
+
if not ModuloStringhe.isEmpty(output):
|
147
|
+
raise EccezioneRuntime(output)
|
148
|
+
return percorsoFileBackup
|
149
|
+
|
150
|
+
@staticmethod
|
151
|
+
def getTableOptions(isDebug: bool) -> str:
|
152
|
+
return "ENGINE=%s DEFAULT CHARSET=utf8"%("InnoDB" if not isDebug else "MEMORY",)
|
153
|
+
|
154
|
+
def paginazione(firstResult:int,numResults:int)->str:
|
155
|
+
sql=("LIMIT "+str(numResults) if numResults is not None else "")+\
|
156
|
+
(" OFFSET "+str(firstResult) if firstResult is not None else "")
|
157
|
+
return sql
|
158
|
+
|
159
|
+
def add_param_list(lista:list,prefix:str)->dict:
|
160
|
+
params={}
|
161
|
+
for index,elem in enumerate(lista):
|
162
|
+
params[prefix+str(index)]=elem
|
163
|
+
return params
|
@@ -1,47 +1,47 @@
|
|
1
|
-
from typing import Optional
|
2
|
-
|
3
|
-
from mysql.connector import FieldType
|
4
|
-
from mysql.connector.conversion import MySQLConverter
|
5
|
-
from mysql.connector.types import DescriptionType
|
6
|
-
from mysql.connector.types import MySQLConvertibleType
|
7
|
-
from mysql.connector.types import MySQLProducedType
|
8
|
-
from mysql.connector.types import PythonProducedType
|
9
|
-
|
10
|
-
|
11
|
-
class MysqlCommonConverter(MySQLConverter):
|
12
|
-
def __init__(self,charset: str|None = None,
|
13
|
-
use_unicode: bool = True,
|
14
|
-
str_fallback: bool = False):
|
15
|
-
super().__init__(charset,use_unicode,str_fallback)
|
16
|
-
|
17
|
-
def to_mysql(self,value) -> MySQLProducedType:
|
18
|
-
value=self.__to_mysql(value)
|
19
|
-
# default behavior
|
20
|
-
return super().to_mysql(value)
|
21
|
-
|
22
|
-
@staticmethod
|
23
|
-
def __to_mysql(value):
|
24
|
-
"""
|
25
|
-
Gestione custom, ad esempio per IntEnum e StrEnum
|
26
|
-
"""
|
27
|
-
if value.__class__ in MySQLConvertibleType.__args__:
|
28
|
-
return value
|
29
|
-
# inizio gestione custom
|
30
|
-
if isinstance(value,int):
|
31
|
-
typePrimitive=int
|
32
|
-
elif isinstance(value,str):
|
33
|
-
typePrimitive=str
|
34
|
-
else:
|
35
|
-
return value
|
36
|
-
value.__class__.__name__=typePrimitive.__name__
|
37
|
-
return value
|
38
|
-
|
39
|
-
def to_python(
|
40
|
-
self,
|
41
|
-
vtype: DescriptionType,
|
42
|
-
value: Optional[bytes],
|
43
|
-
) -> PythonProducedType:
|
44
|
-
if vtype[1] == FieldType.BIT:
|
45
|
-
return value==b'\x01'
|
46
|
-
# default behavior
|
47
|
-
return super().to_python(vtype, value)
|
1
|
+
from typing import Optional
|
2
|
+
|
3
|
+
from mysql.connector import FieldType
|
4
|
+
from mysql.connector.conversion import MySQLConverter
|
5
|
+
from mysql.connector.types import DescriptionType
|
6
|
+
from mysql.connector.types import MySQLConvertibleType
|
7
|
+
from mysql.connector.types import MySQLProducedType
|
8
|
+
from mysql.connector.types import PythonProducedType
|
9
|
+
|
10
|
+
|
11
|
+
class MysqlCommonConverter(MySQLConverter):
|
12
|
+
def __init__(self,charset: str|None = None,
|
13
|
+
use_unicode: bool = True,
|
14
|
+
str_fallback: bool = False):
|
15
|
+
super().__init__(charset,use_unicode,str_fallback)
|
16
|
+
|
17
|
+
def to_mysql(self,value) -> MySQLProducedType:
|
18
|
+
value=self.__to_mysql(value)
|
19
|
+
# default behavior
|
20
|
+
return super().to_mysql(value)
|
21
|
+
|
22
|
+
@staticmethod
|
23
|
+
def __to_mysql(value):
|
24
|
+
"""
|
25
|
+
Gestione custom, ad esempio per IntEnum e StrEnum
|
26
|
+
"""
|
27
|
+
if value.__class__ in MySQLConvertibleType.__args__:
|
28
|
+
return value
|
29
|
+
# inizio gestione custom
|
30
|
+
if isinstance(value,int):
|
31
|
+
typePrimitive=int
|
32
|
+
elif isinstance(value,str):
|
33
|
+
typePrimitive=str
|
34
|
+
else:
|
35
|
+
return value
|
36
|
+
value.__class__.__name__=typePrimitive.__name__
|
37
|
+
return value
|
38
|
+
|
39
|
+
def to_python(
|
40
|
+
self,
|
41
|
+
vtype: DescriptionType,
|
42
|
+
value: Optional[bytes],
|
43
|
+
) -> PythonProducedType:
|
44
|
+
if vtype[1] == FieldType.BIT:
|
45
|
+
return value==b'\x01'
|
46
|
+
# default behavior
|
47
|
+
return super().to_python(vtype, value)
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import mysql.connector
|
2
|
-
|
3
|
-
class EccezioneMysqlOffline(mysql.connector.InterfaceError):
|
4
|
-
|
5
|
-
def __init__(self,*args,**kwargs):
|
6
|
-
super().__init__(*args,**kwargs)
|
1
|
+
import mysql.connector
|
2
|
+
|
3
|
+
class EccezioneMysqlOffline(mysql.connector.InterfaceError):
|
4
|
+
|
5
|
+
def __init__(self,*args,**kwargs):
|
6
|
+
super().__init__(*args,**kwargs)
|