modulitiz-micro 2.26.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.
- modulitiz_micro/ModuloBase64.py +61 -0
- modulitiz_micro/ModuloColorText.py +35 -0
- modulitiz_micro/ModuloDate.py +295 -0
- modulitiz_micro/ModuloFunzioni.py +58 -0
- modulitiz_micro/ModuloListe.py +150 -0
- modulitiz_micro/ModuloMeteo.py +72 -0
- modulitiz_micro/ModuloNumeri.py +130 -0
- modulitiz_micro/ModuloPyinstaller.py +29 -0
- modulitiz_micro/ModuloSeriale.py +61 -0
- modulitiz_micro/ModuloStatistiche.py +31 -0
- modulitiz_micro/ModuloStringhe.py +180 -0
- modulitiz_micro/ModuloTarghe.py +46 -0
- modulitiz_micro/android/ModuloAndroid.py +18 -0
- modulitiz_micro/android/ModuloAndroidAdb.py +48 -0
- modulitiz_micro/android/ModuloAndroidSim.py +130 -0
- modulitiz_micro/android/beans/SmsBean.py +12 -0
- modulitiz_micro/android/enums/AndroidSmsTypeEnum.py +17 -0
- modulitiz_micro/database/AbstractDatabaseService.py +13 -0
- modulitiz_micro/database/AbstractSql.py +49 -0
- modulitiz_micro/database/ModuloSqlOracle.py +19 -0
- modulitiz_micro/database/ModuloSqlServer.py +50 -0
- modulitiz_micro/database/eccezioni/EccezioneDbNoData.py +6 -0
- modulitiz_micro/database/mysql/AbstractBasicMysql.py +114 -0
- modulitiz_micro/database/mysql/ModuloMysql.py +151 -0
- modulitiz_micro/database/mysql/MysqlCommonConverter.py +47 -0
- modulitiz_micro/database/mysql/eccezioni/EccezioneMysqlOffline.py +6 -0
- modulitiz_micro/database/sqlite/AbstractBasicSQLite.py +114 -0
- modulitiz_micro/database/sqlite/ModuloSQLite.py +82 -0
- modulitiz_micro/eccezioni/EccezioneBase.py +7 -0
- modulitiz_micro/eccezioni/EccezioneCtrlC.py +7 -0
- modulitiz_micro/eccezioni/EccezioneRuntime.py +7 -0
- modulitiz_micro/eccezioni/EccezioneScheduler.py +7 -0
- modulitiz_micro/eccezioni/EccezioneSoNonSupportato.py +7 -0
- modulitiz_micro/eccezioni/http/EccezioneHttp.py +8 -0
- modulitiz_micro/eccezioni/http/EccezioneHttp404.py +7 -0
- modulitiz_micro/eccezioni/http/EccezioneHttpGeneric.py +7 -0
- modulitiz_micro/files/ModuloFiles.py +173 -0
- modulitiz_micro/files/ModuloLogging.py +69 -0
- modulitiz_micro/files/ModuloZip.py +42 -0
- modulitiz_micro/files/cache/CacheBean.py +5 -0
- modulitiz_micro/files/cache/CacheRam.py +29 -0
- modulitiz_micro/files/cache/DatabaseCache.py +91 -0
- modulitiz_micro/files/cache/decorators/cacheRam.py +26 -0
- modulitiz_micro/files/git/ModuloGit.py +15 -0
- modulitiz_micro/gestionedom/GestioneDom.py +44 -0
- modulitiz_micro/init/AbstractBasicInit.py +27 -0
- modulitiz_micro/init/AbstractInit.py +11 -0
- modulitiz_micro/keylogger/EccezioneKeyLogger.py +7 -0
- modulitiz_micro/keylogger/ModuloKeylogger.py +73 -0
- modulitiz_micro/multithreading/ModuloThread.py +26 -0
- modulitiz_micro/multithreading/ModuloThreadLogger.py +8 -0
- modulitiz_micro/multithreading/ModuloThreadWithCallbackError.py +25 -0
- modulitiz_micro/nlp/ModuloNlp.py +36 -0
- modulitiz_micro/nlp/ModuloNlpDateAndTime.py +59 -0
- modulitiz_micro/rete/ModuloEmail.py +69 -0
- modulitiz_micro/rete/ModuloNetworking.py +64 -0
- modulitiz_micro/rete/ModuloOpenVpn.py +15 -0
- modulitiz_micro/rete/http/ModuloHttp.py +114 -0
- modulitiz_micro/rete/http/ModuloHttpConnectionSafe.py +91 -0
- modulitiz_micro/rete/http/ModuloHttpUtils.py +66 -0
- modulitiz_micro/rete/http/beans/HttpResponseBean.py +5 -0
- modulitiz_micro/rete/http/decorators/catchAndRaiseHttpExceptions.py +22 -0
- modulitiz_micro/rete/ntp/AbstractModuloNtp.py +73 -0
- modulitiz_micro/rete/ntp/ModuloNtpIt.py +8 -0
- modulitiz_micro/rete/socketserver/AbstractBasicGetSocketServer.py +35 -0
- modulitiz_micro/rete/socketserver/AbstractSocketServer.py +267 -0
- modulitiz_micro/rete/ssl/ModuloSsl.py +56 -0
- modulitiz_micro/sistema/EnvVarsEnum.py +9 -0
- modulitiz_micro/sistema/ModuloEnvVars.py +34 -0
- modulitiz_micro/sistema/ModuloSystem.py +298 -0
- modulitiz_micro/sistema/ModuloSystemPipe.py +67 -0
- modulitiz_micro/social/telegram/ModuloTelegram.py +52 -0
- modulitiz_micro/social/telegram/ModuloTelegramSimple.py +26 -0
- modulitiz_micro/util/beans/conf/AbstractBasicConfBean.py +11 -0
- modulitiz_micro/util/beans/conf/AbstractConfBean.py +16 -0
- modulitiz_micro/util/beans/fileconf/AbstractBasicFileConfBean.py +11 -0
- modulitiz_micro/util/beans/fileconf/AbstractFileConfBean.py +13 -0
- modulitiz_micro/util/beans/globalvar/AbstractBasicGlobalVarBean.py +15 -0
- modulitiz_micro/util/beans/globalvar/AbstractGlobalVarBean.py +34 -0
- modulitiz_micro/util/decorators/noAwait.py +23 -0
- modulitiz_micro/util/pip/AbstractModuloPip.py +41 -0
- modulitiz_micro/util/pip/ModuloPip.py +49 -0
- modulitiz_micro/util/scheduler/AbstractScheduler.py +32 -0
- modulitiz_micro/util/spooler/AbstractSpooler.py +14 -0
- modulitiz_micro/util/spooler/Spooler.py +18 -0
- modulitiz_micro/util/spooler/beans/QueueBean.py +8 -0
- modulitiz_micro/util/spooler/decorators/spooler.py +49 -0
- modulitiz_micro/util/spooler/eccezioni/EccezioneSpooler.py +7 -0
- modulitiz_micro/util/spooler/eccezioni/EccezioneSpoolerFull.py +7 -0
- modulitiz_micro/util/unittesting/AbstractOverrideTestUtil.py +18 -0
- modulitiz_micro/util/unittesting/AbstractTestUtil.py +11 -0
- modulitiz_micro/util/unittesting/ModuloRunUnitTest.py +25 -0
- modulitiz_micro/util/wheel/ModuloBuildWheel.py +118 -0
- modulitiz_micro/util/wheel/ModuloToml.py +40 -0
- modulitiz_micro/util/wheel/ModuloWheel.py +12 -0
- modulitiz_micro-2.26.0.dist-info/LICENSE +21 -0
- modulitiz_micro-2.26.0.dist-info/METADATA +63 -0
- modulitiz_micro-2.26.0.dist-info/RECORD +100 -0
- modulitiz_micro-2.26.0.dist-info/WHEEL +5 -0
- modulitiz_micro-2.26.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
from enum import IntEnum
|
2
|
+
from enum import auto
|
3
|
+
from enum import unique
|
4
|
+
|
5
|
+
|
6
|
+
@unique
|
7
|
+
class AndroidSmsTypeEnum(IntEnum):
|
8
|
+
"""
|
9
|
+
Tipi di sms/mms
|
10
|
+
"""
|
11
|
+
ALL=0
|
12
|
+
RECEIVED=auto()
|
13
|
+
SENT=auto()
|
14
|
+
DRAFT=auto()
|
15
|
+
OUTBOX=auto()
|
16
|
+
FAILED_OUTGOING=auto()
|
17
|
+
QUEUED=auto()
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import threading
|
2
|
+
from abc import ABC
|
3
|
+
|
4
|
+
from modulitiz_micro.files.ModuloLogging import ModuloLogging
|
5
|
+
|
6
|
+
|
7
|
+
class AbstractDatabaseService(ABC):
|
8
|
+
|
9
|
+
def __init__(self,logger:ModuloLogging):
|
10
|
+
self._logger=logger
|
11
|
+
self.lock=threading.Lock()
|
12
|
+
|
13
|
+
self.database=None
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import threading
|
2
|
+
from abc import ABC
|
3
|
+
|
4
|
+
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
5
|
+
|
6
|
+
|
7
|
+
class AbstractSql(ABC):
|
8
|
+
def __init__(self):
|
9
|
+
self.connDb=None
|
10
|
+
self.lock=threading.Lock()
|
11
|
+
|
12
|
+
def commit(self):
|
13
|
+
with self.lock:
|
14
|
+
self.commitNoLock()
|
15
|
+
|
16
|
+
def commitNoLock(self):
|
17
|
+
"""
|
18
|
+
Da usare solo se il lock viene fatto esternamente
|
19
|
+
"""
|
20
|
+
self.connDb.commit()
|
21
|
+
|
22
|
+
def rollback(self):
|
23
|
+
with self.lock:
|
24
|
+
self.connDb.rollback()
|
25
|
+
|
26
|
+
def initCursore(self):
|
27
|
+
with self.lock:
|
28
|
+
cursoreDb=self.connDb.cursor()
|
29
|
+
return cursoreDb
|
30
|
+
|
31
|
+
def count(self,cursoreDb)->int:
|
32
|
+
with cursoreDb:
|
33
|
+
with self.lock:
|
34
|
+
result=cursoreDb.fetchone()
|
35
|
+
if not result:
|
36
|
+
return 0
|
37
|
+
return result[0]
|
38
|
+
|
39
|
+
def close(self):
|
40
|
+
with self.lock:
|
41
|
+
if self.connDb is not None:
|
42
|
+
self.connDb.close()
|
43
|
+
self.connDb=None
|
44
|
+
|
45
|
+
@staticmethod
|
46
|
+
def ifEmptyThenNull(testo:str|None)->str|None:
|
47
|
+
if ModuloStringhe.isEmpty(testo) or testo=="NULL":
|
48
|
+
return None
|
49
|
+
return testo
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import oracledb
|
2
|
+
|
3
|
+
from modulitiz_micro.database.ModuloSqlServer import ModuloSqlServer
|
4
|
+
|
5
|
+
|
6
|
+
class ModuloSqlOracle(ModuloSqlServer):
|
7
|
+
DEFAULT_PORTA=1521
|
8
|
+
|
9
|
+
def __init__(self,porta:int|None,*args,**kwargs):
|
10
|
+
super().__init__(*args,**kwargs)
|
11
|
+
if porta is None:
|
12
|
+
porta=self.DEFAULT_PORTA
|
13
|
+
self.porta=porta
|
14
|
+
|
15
|
+
def connessione(self):
|
16
|
+
dsn="{}/{}@{}:{}/xe".format(self.username,self.password,self.host,self.porta)
|
17
|
+
self.connDb=oracledb.connect(dsn)
|
18
|
+
self.connDb=dsn
|
19
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import pypyodbc
|
2
|
+
|
3
|
+
from modulitiz_micro.database.AbstractSql import AbstractSql
|
4
|
+
|
5
|
+
|
6
|
+
class ModuloSqlServer(AbstractSql):
|
7
|
+
ERROR_CODE__UNIQUE_INDEX=23000
|
8
|
+
|
9
|
+
def __init__(self,host:str,nome_db:str,username:str,password:str):
|
10
|
+
super().__init__()
|
11
|
+
self.host=host
|
12
|
+
self.nome_db=nome_db
|
13
|
+
self.username=username
|
14
|
+
self.password=password
|
15
|
+
|
16
|
+
def connessione(self):
|
17
|
+
connDb=pypyodbc.connect("Driver={SQL Server};Server="+self.host+";Database="+self.nome_db+";uid="+self.username+";pwd="+self.password+";")
|
18
|
+
self.connDb=connDb
|
19
|
+
|
20
|
+
def select(self,sql:str,params:list):
|
21
|
+
with self.initCursore() as cursoreDb:
|
22
|
+
cursoreDb.execute(sql,params)
|
23
|
+
results=list(cursoreDb)
|
24
|
+
return results
|
25
|
+
|
26
|
+
@staticmethod
|
27
|
+
def selectOne(cursoreDb,sql:str,params:list)->list:
|
28
|
+
"""
|
29
|
+
Scarica la prima riga della query
|
30
|
+
"""
|
31
|
+
with cursoreDb:
|
32
|
+
cursoreDb.execute(sql,params)
|
33
|
+
element=cursoreDb.fetchone()
|
34
|
+
return list(element)
|
35
|
+
|
36
|
+
def select_count(self,cursoreDb,sql:str,params:list)->int:
|
37
|
+
elemento=self.selectOne(cursoreDb,sql,params)
|
38
|
+
return int(elemento[0])
|
39
|
+
|
40
|
+
#usare se si vogliono fare delle modifiche ai dati
|
41
|
+
#tipo: insert, update, delete
|
42
|
+
def modifica(self,cursoreDb,sql:str,params:list,ignore_unique_index:bool):
|
43
|
+
try:
|
44
|
+
cursoreDb.execute(sql,params)
|
45
|
+
except pypyodbc.IntegrityError as ie:
|
46
|
+
if ignore_unique_index:
|
47
|
+
error_code=int(ie.value[0])
|
48
|
+
if error_code!=self.ERROR_CODE__UNIQUE_INDEX:
|
49
|
+
raise ie
|
50
|
+
|
@@ -0,0 +1,114 @@
|
|
1
|
+
from abc import abstractmethod
|
2
|
+
|
3
|
+
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
4
|
+
from modulitiz_micro.database.mysql.ModuloMysql import AbstractMysql
|
5
|
+
|
6
|
+
|
7
|
+
class AbstractBasicMysql(AbstractMysql):
|
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 risultati in self.executeScript(sqlStr):
|
17
|
+
yield risultati
|
18
|
+
sqlInsertBasicTables=self.insertBasicTables()
|
19
|
+
if not ModuloStringhe.isEmpty(sqlInsertBasicTables):
|
20
|
+
sqlInsertBasicTables=ModuloStringhe.normalizzaEol(sqlInsertBasicTables)
|
21
|
+
for risultati in self.executeScript(sqlInsertBasicTables):
|
22
|
+
yield risultati
|
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.initCursore()
|
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.initCursore()
|
111
|
+
with self.lock:
|
112
|
+
cursoreDb.execute(sql,params)
|
113
|
+
return cursoreDb
|
114
|
+
|
@@ -0,0 +1,151 @@
|
|
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 AbstractMysql(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.initCursore()
|
39
|
+
self.TABLE_OPTIONS=self.getTableOptions(isDebug)
|
40
|
+
self.isDbNew=None
|
41
|
+
|
42
|
+
def initDdl(self):
|
43
|
+
#scelgo il db
|
44
|
+
try:
|
45
|
+
self.connDb.cmd_init_db(self.nomeDb)
|
46
|
+
self.isDbNew=False
|
47
|
+
except mysql.connector.ProgrammingError:
|
48
|
+
sqlCreaDb="CREATE DATABASE %s;"%(self.nomeDb,)
|
49
|
+
with self.initCursore() as cursoreDb:
|
50
|
+
with self.lock:
|
51
|
+
cursoreDb.execute(sqlCreaDb)
|
52
|
+
self.connDb.cmd_init_db(self.nomeDb)
|
53
|
+
self.isDbNew=True
|
54
|
+
#se il db non esisteva creo le tabelle
|
55
|
+
if self.isDbNew:
|
56
|
+
sqlStr=ModuloStringhe.normalizzaEol(self.schema())
|
57
|
+
for risultati in self.executeScript(sqlStr):
|
58
|
+
yield risultati
|
59
|
+
|
60
|
+
@abstractmethod
|
61
|
+
def schema(self):
|
62
|
+
"""
|
63
|
+
Inserire le istruzioni sql contenenti la dichiarazione delle tabelle (DDL)
|
64
|
+
"""
|
65
|
+
|
66
|
+
def getLastIdInserted(self,cursoreDb):
|
67
|
+
return cursoreDb.lastrowid
|
68
|
+
|
69
|
+
def executeScript(self,sqlStr:str):
|
70
|
+
sqlCmds=sqlStr.split(";")
|
71
|
+
sqlCmds=ModuloListe.eliminaElementiVuoti(sqlCmds)
|
72
|
+
numCmds=len(sqlCmds)
|
73
|
+
cursoreDb=self.initCursore()
|
74
|
+
for index,sqlCmd in enumerate(sqlCmds):
|
75
|
+
sqlCmd=sqlCmd.strip()
|
76
|
+
try:
|
77
|
+
if sqlCmd!="":
|
78
|
+
with self.lock:
|
79
|
+
cursoreDb.execute(sqlCmd)
|
80
|
+
yield index,numCmds
|
81
|
+
except Exception as ex:
|
82
|
+
raise EccezioneRuntime(sqlCmd+"\n\n"+ModuloLogging.exceptionToString(ex))
|
83
|
+
|
84
|
+
def fetchAll(self,cursoreDb)->list:
|
85
|
+
with cursoreDb:
|
86
|
+
if cursoreDb.description is None:
|
87
|
+
raise EccezioneDbNoData()
|
88
|
+
descriptions=cursoreDb.description
|
89
|
+
with self.lock:
|
90
|
+
rows=cursoreDb.fetchall()
|
91
|
+
self.commitNoLock() # mysql mette in cache i risultati, lo risolvo così, è un bug loro...
|
92
|
+
columns = [col[0] for col in descriptions]
|
93
|
+
rows = [dict(zip(columns, row)) for row in rows]
|
94
|
+
return rows
|
95
|
+
|
96
|
+
@classmethod
|
97
|
+
def backup(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
98
|
+
ignoreTables:list|tuple|None)->list:
|
99
|
+
output=[
|
100
|
+
cls.backupDdl(percorsoCartella,user,password,dbName,ignoreTables),
|
101
|
+
cls.backupData(percorsoCartella,user,password,dbName,ignoreTables)
|
102
|
+
]
|
103
|
+
return output
|
104
|
+
|
105
|
+
@classmethod
|
106
|
+
def backupDdl(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
107
|
+
ignoreTables:list|tuple|None)->str:
|
108
|
+
return cls.__backup(percorsoCartella,user,password,dbName,ignoreTables,True,False)
|
109
|
+
@classmethod
|
110
|
+
def backupData(cls,percorsoCartella: str,user: str,password: str,dbName: str,
|
111
|
+
ignoreTables:list|tuple|None)->str:
|
112
|
+
return cls.__backup(percorsoCartella,user,password,dbName,ignoreTables,False,True)
|
113
|
+
|
114
|
+
@staticmethod
|
115
|
+
def __backup(percorsoCartella:str,user:str,password:str,dbName:str,
|
116
|
+
ignoreTables:list|tuple|None,onlyDdl:bool,onlyData:bool)->str:
|
117
|
+
if onlyDdl and onlyData:
|
118
|
+
raise EccezioneRuntime("valorizzare solo un'opzione alla volta")
|
119
|
+
cmdIgnoreTables=""
|
120
|
+
if ignoreTables is not None:
|
121
|
+
cmdIgnoreTables=" ".join(["--ignore-table=%s.%s"%(dbName,x) for x in ignoreTables])
|
122
|
+
nomefileSuffix=""
|
123
|
+
cmdOptions=""
|
124
|
+
if onlyDdl:
|
125
|
+
nomefileSuffix="_ddl"
|
126
|
+
cmdOptions="--no-data "+cmdIgnoreTables
|
127
|
+
elif onlyData:
|
128
|
+
nomefileSuffix="_data"
|
129
|
+
cmdOptions="--order-by-primary --no-create-info --quick "+cmdIgnoreTables
|
130
|
+
nomefileOutput=dbName+nomefileSuffix+".sql"
|
131
|
+
percorsoFileBackup=ModuloFiles.pathJoin(percorsoCartella,nomefileOutput)
|
132
|
+
cmd=r'mysqldump -u {} -p{} --databases {} --skip-add-drop-table --skip-comments {} -r "{}"'.format(user,password,dbName,cmdOptions,percorsoFileBackup)
|
133
|
+
output=ModuloSystem.systemCallReturnOutput(cmd,None).strip()
|
134
|
+
if not ModuloStringhe.isEmpty(output):
|
135
|
+
raise EccezioneRuntime(output)
|
136
|
+
return percorsoFileBackup
|
137
|
+
|
138
|
+
@staticmethod
|
139
|
+
def getTableOptions(isDebug: bool) -> str:
|
140
|
+
return "ENGINE=%s DEFAULT CHARSET=utf8"%("InnoDB" if not isDebug else "MEMORY",)
|
141
|
+
|
142
|
+
def paginazione(firstResult:int,numResults:int)->str:
|
143
|
+
sql=("LIMIT "+str(numResults) if numResults is not None else "")+\
|
144
|
+
(" OFFSET "+str(firstResult) if firstResult is not None else "")
|
145
|
+
return sql
|
146
|
+
|
147
|
+
def add_param_list(lista:list,prefix:str)->dict:
|
148
|
+
params={}
|
149
|
+
for index,elem in enumerate(lista):
|
150
|
+
params[prefix+str(index)]=elem
|
151
|
+
return params
|
@@ -0,0 +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)
|
@@ -0,0 +1,114 @@
|
|
1
|
+
from abc import abstractmethod
|
2
|
+
|
3
|
+
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
4
|
+
from modulitiz_micro.database.sqlite.ModuloSQLite import AbstractSqlite
|
5
|
+
|
6
|
+
|
7
|
+
class AbstractBasicSqlite(AbstractSqlite):
|
8
|
+
|
9
|
+
def __init__(self,*args,**kwargs):
|
10
|
+
super().__init__(*args,**kwargs)
|
11
|
+
if not self.isDbNew:
|
12
|
+
return
|
13
|
+
sql_str=ModuloStringhe.normalizzaEol(self.schemaBasicTables())
|
14
|
+
with self.initCursore() as cursoreDb:
|
15
|
+
with self.lock:
|
16
|
+
cursoreDb.executescript(sql_str)
|
17
|
+
sql_insertBasicTables=self.insertBasicTables()
|
18
|
+
if not ModuloStringhe.isEmpty(sql_insertBasicTables):
|
19
|
+
sql_insertBasicTables=ModuloStringhe.normalizzaEol(sql_insertBasicTables)
|
20
|
+
with self.lock:
|
21
|
+
cursoreDb.executescript(sql_insertBasicTables)
|
22
|
+
self.commit()
|
23
|
+
|
24
|
+
@abstractmethod
|
25
|
+
def insertBasicTables(self):
|
26
|
+
"""
|
27
|
+
Inserire le istruzioni sql che vanno eseguite alla fine di tutto
|
28
|
+
"""
|
29
|
+
|
30
|
+
def schemaBasicTables(self):
|
31
|
+
return """
|
32
|
+
|
33
|
+
CREATE TABLE tb_params(
|
34
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
35
|
+
type TEXT NOT NULL,
|
36
|
+
key TEXT NULL,
|
37
|
+
desc TEXT NOT NULL,
|
38
|
+
enabled INTEGER NOT NULL,
|
39
|
+
lang_code TEXT NULL,
|
40
|
+
data_insert TIMESTAMP NOT NULL
|
41
|
+
);
|
42
|
+
CREATE UNIQUE INDEX PARAMS__UK1 ON tb_params(
|
43
|
+
type,
|
44
|
+
IFNULL(key, 0),
|
45
|
+
IFNULL(lang_code, 0)
|
46
|
+
);
|
47
|
+
|
48
|
+
"""
|
49
|
+
|
50
|
+
|
51
|
+
#############################################################################################################################
|
52
|
+
#############################################################################################################################
|
53
|
+
#############################################################################################################################
|
54
|
+
def selectParamDescByEntries(self,paramType,paramKey)->str|None:
|
55
|
+
with self.selectParamByEntries(paramType, paramKey, None, True) as cursoreDb:
|
56
|
+
results=cursoreDb.fetchall()
|
57
|
+
if len(results)==0:
|
58
|
+
return None
|
59
|
+
return results[0]['desc']
|
60
|
+
|
61
|
+
def selectParamByEntries(self,paramType,paramKey,langCode,enabled):
|
62
|
+
addParamKey=ModuloStringhe.isEmpty(paramKey) is False
|
63
|
+
addLangCode=ModuloStringhe.isEmpty(langCode) is False
|
64
|
+
addEnabled=ModuloStringhe.isEmpty(enabled) is False
|
65
|
+
|
66
|
+
sql="""
|
67
|
+
SELECT *
|
68
|
+
FROM tb_params
|
69
|
+
WHERE type=:paramType
|
70
|
+
"""+("AND key=:paramKey" if addParamKey is True else "")+"""
|
71
|
+
"""+("AND langCode=:langCode" if addLangCode is True else "")+"""
|
72
|
+
"""+("AND enabled=:enabled" if addEnabled is True else "")+"""
|
73
|
+
;
|
74
|
+
"""
|
75
|
+
params={'paramType':paramType}
|
76
|
+
if addParamKey is True:
|
77
|
+
params['paramKey']=paramKey
|
78
|
+
if addLangCode is True:
|
79
|
+
params['langCode']=langCode
|
80
|
+
if addEnabled is True:
|
81
|
+
params['enabled']=enabled
|
82
|
+
cursoreDb=self.initCursore()
|
83
|
+
with self.lock:
|
84
|
+
cursoreDb.execute(sql,params)
|
85
|
+
return cursoreDb
|
86
|
+
|
87
|
+
|
88
|
+
def updateParamDesc(self,paramType,paramKey,newDesc):
|
89
|
+
addParamKey=ModuloStringhe.isEmpty(paramKey) is False
|
90
|
+
addNewDesc=ModuloStringhe.isEmpty(newDesc) is False
|
91
|
+
|
92
|
+
sql_set=[]
|
93
|
+
if addNewDesc is True:
|
94
|
+
sql_set.append("desc=:newDesc")
|
95
|
+
sql_set=", ".join(sql_set)
|
96
|
+
|
97
|
+
sql="""
|
98
|
+
UPDATE tb_params
|
99
|
+
SET """+sql_set+"""
|
100
|
+
WHERE type=:paramType
|
101
|
+
"""+("AND key=:paramKey" 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.initCursore()
|
111
|
+
with self.lock:
|
112
|
+
cursoreDb.execute(sql,params)
|
113
|
+
return cursoreDb
|
114
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
"""
|
2
|
+
esempio utilizzo per lista
|
3
|
+
|
4
|
+
def __query_NOME_TABELLA(self,lista_status,is_count):
|
5
|
+
paramsStatus=ModuloSQLite.add_param_list(lista_status, "status")
|
6
|
+
|
7
|
+
sql='''
|
8
|
+
SELECT '''+("COUNT(*)" if is_count is True else "*")+'''
|
9
|
+
FROM NOME_TABELLA
|
10
|
+
WHERE 1=1
|
11
|
+
AND status IN (:'''+",:".join(paramsStatus.keys())+''')
|
12
|
+
;
|
13
|
+
'''
|
14
|
+
cursoreDb.execute(sql,paramsStatus)
|
15
|
+
"""
|
16
|
+
import sqlite3
|
17
|
+
from abc import abstractmethod
|
18
|
+
|
19
|
+
from modulitiz_micro.ModuloStringhe import ModuloStringhe
|
20
|
+
from modulitiz_micro.database.AbstractSql import AbstractSql
|
21
|
+
from modulitiz_micro.files.ModuloFiles import ModuloFiles
|
22
|
+
|
23
|
+
|
24
|
+
class AbstractSqlite(AbstractSql):
|
25
|
+
"""
|
26
|
+
select
|
27
|
+
count
|
28
|
+
insert
|
29
|
+
update
|
30
|
+
delete
|
31
|
+
"""
|
32
|
+
|
33
|
+
DATE_TIME_NOW="datetime('now','localtime')"
|
34
|
+
DATE_TIME_NOW_MILLIS="strftime('%Y-%m-%d %H:%M:%f', 'now')"
|
35
|
+
|
36
|
+
TIMEOUT_CONNECTION=10
|
37
|
+
|
38
|
+
|
39
|
+
def __init__(self,nomefile_db:str,show_sql:bool=False):
|
40
|
+
super().__init__()
|
41
|
+
self.isDbNew=ModuloFiles.getFileSize(nomefile_db)<=0
|
42
|
+
#apro la connessione col db
|
43
|
+
connDb=sqlite3.connect(nomefile_db, timeout=self.TIMEOUT_CONNECTION, detect_types=sqlite3.PARSE_DECLTYPES, check_same_thread=False)
|
44
|
+
#modifica row factory per usare Row
|
45
|
+
connDb.row_factory=sqlite3.Row
|
46
|
+
self.connDb=connDb
|
47
|
+
# creo il cursore, deve essere fatto dopo il row factory
|
48
|
+
with self.initCursore() as cursoreDb:
|
49
|
+
# setup iniziale
|
50
|
+
with self.lock:
|
51
|
+
# non puoi cancellare un record se e' referenziato da un'altra tabella
|
52
|
+
cursoreDb.executescript('PRAGMA foreign_keys=ON;')
|
53
|
+
self.commit()
|
54
|
+
# mostra i comandi sql eseguiti
|
55
|
+
if show_sql is True:
|
56
|
+
self.connDb.set_trace_callback(print)
|
57
|
+
# se il db non esisteva creo le tabelle
|
58
|
+
if self.isDbNew:
|
59
|
+
sql_str=ModuloStringhe.normalizzaEol(self.schema())
|
60
|
+
with self.lock:
|
61
|
+
cursoreDb.executescript(sql_str)
|
62
|
+
self.commit()
|
63
|
+
|
64
|
+
@abstractmethod
|
65
|
+
def schema(self):
|
66
|
+
"""
|
67
|
+
Inserire le istruzioni sql contenenti la dichiarazione delle tabelle (DDL)
|
68
|
+
"""
|
69
|
+
|
70
|
+
def getLastIdInserted(self,cursoreDb):
|
71
|
+
return cursoreDb.lastrowid
|
72
|
+
|
73
|
+
def paginazione(first_result:int,num_results:int)->str:
|
74
|
+
sql=("LIMIT "+str(num_results) if num_results is not None else "")
|
75
|
+
sql+=(" OFFSET "+str(first_result) if first_result is not None else "")
|
76
|
+
return sql
|
77
|
+
|
78
|
+
def add_param_list(lista,prefix):
|
79
|
+
params={}
|
80
|
+
for index,elem in enumerate(lista):
|
81
|
+
params[prefix+str(index)]=elem
|
82
|
+
return params
|