modulitiz-micro 2.32.0__py311-none-any.whl → 2.33.0__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.
Files changed (105) hide show
  1. modulitiz_micro/ModuloBase64.py +61 -61
  2. modulitiz_micro/ModuloColorText.py +35 -35
  3. modulitiz_micro/ModuloDate.py +295 -295
  4. modulitiz_micro/ModuloFunzioni.py +70 -70
  5. modulitiz_micro/ModuloListe.py +150 -150
  6. modulitiz_micro/ModuloMeteo.py +72 -72
  7. modulitiz_micro/ModuloNumeri.py +130 -130
  8. modulitiz_micro/ModuloPyinstaller.py +29 -29
  9. modulitiz_micro/ModuloSeriale.py +61 -61
  10. modulitiz_micro/ModuloStatistiche.py +31 -31
  11. modulitiz_micro/ModuloStringhe.py +180 -180
  12. modulitiz_micro/ModuloTarghe.py +46 -46
  13. modulitiz_micro/android/ModuloAndroid.py +18 -18
  14. modulitiz_micro/android/ModuloAndroidAdb.py +48 -48
  15. modulitiz_micro/android/ModuloAndroidSim.py +130 -130
  16. modulitiz_micro/android/beans/SmsBean.py +12 -12
  17. modulitiz_micro/android/enums/AndroidSmsTypeEnum.py +17 -17
  18. modulitiz_micro/database/AbstractDatabaseService.py +13 -13
  19. modulitiz_micro/database/AbstractSql.py +69 -69
  20. modulitiz_micro/database/ModuloSqlOracle.py +19 -19
  21. modulitiz_micro/database/ModuloSqlServer.py +43 -43
  22. modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -6
  23. modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -114
  24. modulitiz_micro/database/mysql/ModuloMysql.py +163 -163
  25. modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -47
  26. modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -6
  27. modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -114
  28. modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -82
  29. modulitiz_micro/eccezioni/EccezioneBase.py +7 -7
  30. modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -7
  31. modulitiz_micro/eccezioni/EccezioneRuntime.py +7 -7
  32. modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -7
  33. modulitiz_micro/eccezioni/EccezioneSoNonSupportato.py +7 -7
  34. modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -8
  35. modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -7
  36. modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -7
  37. modulitiz_micro/files/ModuloFiles.py +173 -173
  38. modulitiz_micro/files/ModuloLogging.py +69 -69
  39. modulitiz_micro/files/ModuloZip.py +42 -42
  40. modulitiz_micro/files/cache/CacheBean.py +5 -5
  41. modulitiz_micro/files/cache/CacheRam.py +29 -29
  42. modulitiz_micro/files/cache/DatabaseCache.py +91 -91
  43. modulitiz_micro/files/cache/decorators/cacheRam.py +26 -26
  44. modulitiz_micro/files/git/ModuloGit.py +28 -20
  45. modulitiz_micro/files/git/decorators/catchAndRaiseGitExceptions.py +19 -19
  46. modulitiz_micro/files/git/exceptions/EccezioneGit.py +7 -7
  47. modulitiz_micro/gestionedom/GestioneDom.py +44 -44
  48. modulitiz_micro/init/AbstractBasicInit.py +27 -27
  49. modulitiz_micro/init/AbstractInit.py +11 -11
  50. modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -7
  51. modulitiz_micro/keylogger/ModuloKeylogger.py +73 -73
  52. modulitiz_micro/multithread/ModuloThread.py +26 -26
  53. modulitiz_micro/multithread/ModuloThreadLogger.py +8 -8
  54. modulitiz_micro/multithread/ModuloThreadWithCallbackError.py +25 -25
  55. modulitiz_micro/nlp/ModuloNlp.py +36 -36
  56. modulitiz_micro/nlp/ModuloNlpDateAndTime.py +59 -59
  57. modulitiz_micro/rete/ModuloNetworking.py +67 -67
  58. modulitiz_micro/rete/ModuloOpenVpn.py +15 -15
  59. modulitiz_micro/rete/email/EmailBean.py +5 -5
  60. modulitiz_micro/rete/email/ModuloEmail.py +90 -90
  61. modulitiz_micro/rete/http/ModuloHttp.py +115 -115
  62. modulitiz_micro/rete/http/ModuloHttpConnectionSafe.py +91 -91
  63. modulitiz_micro/rete/http/ModuloHttpUtils.py +69 -69
  64. modulitiz_micro/rete/http/beans/HttpResponseBean.py +5 -5
  65. modulitiz_micro/rete/http/decorators/catchAndRaiseHttpExceptions.py +22 -22
  66. modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -73
  67. modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -8
  68. modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -35
  69. modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -267
  70. modulitiz_micro/rete/ssl/ModuloSsl.py +56 -56
  71. modulitiz_micro/sistema/EnvVarsEnum.py +9 -9
  72. modulitiz_micro/sistema/ModuloEnvVars.py +34 -34
  73. modulitiz_micro/sistema/ModuloSystem.py +298 -298
  74. modulitiz_micro/sistema/ModuloSystemPipe.py +67 -67
  75. modulitiz_micro/social/telegram/ModuloTelegram.py +52 -52
  76. modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -26
  77. modulitiz_micro/util/beans/conf/AbstractBasicConfBean.py +11 -11
  78. modulitiz_micro/util/beans/conf/AbstractConfBean.py +16 -16
  79. modulitiz_micro/util/beans/fileconf/AbstractBasicFileConfBean.py +11 -11
  80. modulitiz_micro/util/beans/fileconf/AbstractFileConfBean.py +13 -13
  81. modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -15
  82. modulitiz_micro/util/beans/globalvar/AbstractGlobalVarBean.py +34 -34
  83. modulitiz_micro/util/decorators/noAwait.py +23 -23
  84. modulitiz_micro/util/pip/AbstractModuloPip.py +41 -41
  85. modulitiz_micro/util/pip/ModuloPip.py +49 -49
  86. modulitiz_micro/util/scheduler/AbstractScheduler.py +32 -32
  87. modulitiz_micro/util/spooler/AbstractSpooler.py +14 -14
  88. modulitiz_micro/util/spooler/Spooler.py +18 -18
  89. modulitiz_micro/util/spooler/beans/QueueBean.py +8 -8
  90. modulitiz_micro/util/spooler/decorators/spooler.py +49 -49
  91. modulitiz_micro/util/spooler/eccezioni/EccezioneSpooler.py +7 -7
  92. modulitiz_micro/util/spooler/eccezioni/EccezioneSpoolerFull.py +7 -7
  93. modulitiz_micro/util/unittesting/AbstractOverrideTestUtil.py +31 -31
  94. modulitiz_micro/util/unittesting/AbstractTestUtil.py +11 -11
  95. modulitiz_micro/util/unittesting/ModuloRunUnitTest.py +25 -25
  96. modulitiz_micro/util/wheel/ModuloBuildWheel.py +117 -131
  97. modulitiz_micro/util/wheel/ModuloCheckTestNamingConvention.py +83 -86
  98. modulitiz_micro/util/wheel/ModuloToml.py +40 -40
  99. modulitiz_micro/util/wheel/ModuloWheel.py +12 -12
  100. {modulitiz_micro-2.32.0.dist-info → modulitiz_micro-2.33.0.dist-info}/LICENSE +21 -21
  101. {modulitiz_micro-2.32.0.dist-info → modulitiz_micro-2.33.0.dist-info}/METADATA +64 -64
  102. modulitiz_micro-2.33.0.dist-info/RECORD +104 -0
  103. modulitiz_micro-2.32.0.dist-info/RECORD +0 -104
  104. {modulitiz_micro-2.32.0.dist-info → modulitiz_micro-2.33.0.dist-info}/WHEEL +0 -0
  105. {modulitiz_micro-2.32.0.dist-info → modulitiz_micro-2.33.0.dist-info}/top_level.txt +0 -0
@@ -1,114 +1,114 @@
1
- from abc import abstractmethod
2
-
3
- from modulitiz_micro.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_micro.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_micro.ModuloListe import ModuloListe
6
- from modulitiz_micro.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_micro.eccezioni.EccezioneRuntime import EccezioneRuntime
11
- from modulitiz_micro.files.ModuloFiles import ModuloFiles
12
- from modulitiz_micro.files.ModuloLogging import ModuloLogging
13
- from modulitiz_micro.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_micro.ModuloListe import ModuloListe
6
+ from modulitiz_micro.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_micro.eccezioni.EccezioneRuntime import EccezioneRuntime
11
+ from modulitiz_micro.files.ModuloFiles import ModuloFiles
12
+ from modulitiz_micro.files.ModuloLogging import ModuloLogging
13
+ from modulitiz_micro.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)