dbobj3 0.4.0__tar.gz → 0.6.0__tar.gz
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.
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dbobj3"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.6.0"
|
|
8
8
|
description = "High-level MySQL/MSSQL/Oracle access module"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.6"
|
|
@@ -16,7 +16,7 @@ dependencies = [
|
|
|
16
16
|
packages = ["src/dbobj3.py"]
|
|
17
17
|
|
|
18
18
|
[tool.bumpversion]
|
|
19
|
-
current_version = "0.
|
|
19
|
+
current_version = "0.6.0"
|
|
20
20
|
commit = true
|
|
21
21
|
tag = true
|
|
22
22
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)"
|
|
@@ -21,7 +21,7 @@ Example:
|
|
|
21
21
|
rsServices.next()
|
|
22
22
|
|
|
23
23
|
"""
|
|
24
|
-
__version__ = "0.
|
|
24
|
+
__version__ = "0.6.0"
|
|
25
25
|
|
|
26
26
|
from sys import version as sys_version, exit
|
|
27
27
|
pyversion = sys_version[0:sys_version.find(' ')]
|
|
@@ -95,9 +95,15 @@ try:
|
|
|
95
95
|
import requests
|
|
96
96
|
lstLoadedDrivers.append({"requests": "Loaded (API)"})
|
|
97
97
|
except ImportError:
|
|
98
|
-
#print('could not import
|
|
98
|
+
#print('could not import requests')
|
|
99
99
|
lstLoadedDrivers.append({"requests": "Not Loaded (API)"})
|
|
100
100
|
|
|
101
|
+
try:
|
|
102
|
+
import jaydebeapi
|
|
103
|
+
lstLoadedDrivers.append({"jaydebeapi": "Loaded (JDBC)"})
|
|
104
|
+
except ImportError:
|
|
105
|
+
lstLoadedDrivers.append({"jaydebeapi": "Not Loaded (JDBC)"})
|
|
106
|
+
|
|
101
107
|
try:
|
|
102
108
|
import json
|
|
103
109
|
except ImportError:
|
|
@@ -156,6 +162,8 @@ class dbObjCursor:
|
|
|
156
162
|
self.createProgress()
|
|
157
163
|
elif(prmDBType=="API"):
|
|
158
164
|
self.createAPI()
|
|
165
|
+
elif(prmDBType=="JDBC"):
|
|
166
|
+
self.createJDBC()
|
|
159
167
|
|
|
160
168
|
def createMySql(self):
|
|
161
169
|
self.cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
|
|
@@ -177,6 +185,9 @@ class dbObjCursor:
|
|
|
177
185
|
def createAPI(self):
|
|
178
186
|
self.lstRecords = []
|
|
179
187
|
|
|
188
|
+
def createJDBC(self):
|
|
189
|
+
self.cursor = self.connection.cursor()
|
|
190
|
+
|
|
180
191
|
def moveNext(self):
|
|
181
192
|
"""Same as next"""
|
|
182
193
|
self.next()
|
|
@@ -195,6 +206,8 @@ class dbObjCursor:
|
|
|
195
206
|
self.progressNext()
|
|
196
207
|
elif(self.dbType == "API"):
|
|
197
208
|
self.apiNext()
|
|
209
|
+
elif(self.dbType == "JDBC"):
|
|
210
|
+
self.jdbcNext()
|
|
198
211
|
|
|
199
212
|
def mySqlNext(self):
|
|
200
213
|
resultSet = self.cursor.fetchone()
|
|
@@ -275,6 +288,51 @@ class dbObjCursor:
|
|
|
275
288
|
else:
|
|
276
289
|
self.EOF = 1
|
|
277
290
|
|
|
291
|
+
def jdbcNext(self):
|
|
292
|
+
try:
|
|
293
|
+
resultSet = self.cursor.fetchone()
|
|
294
|
+
except Exception as e:
|
|
295
|
+
print(e)
|
|
296
|
+
self.EOF = 1
|
|
297
|
+
return
|
|
298
|
+
if(resultSet != None):
|
|
299
|
+
columns = [column[0] for column in self.cursor.description]
|
|
300
|
+
self.fieldByName = (dict(zip(columns, resultSet)))
|
|
301
|
+
#self.fieldNames.append(cursorFieldname[0])
|
|
302
|
+
self.fields = self.fieldByName
|
|
303
|
+
self.EOF = 0
|
|
304
|
+
else:
|
|
305
|
+
self.EOF = 1
|
|
306
|
+
|
|
307
|
+
'''
|
|
308
|
+
if(self.recordPointer <= self.numRows): #???? what about 0?
|
|
309
|
+
self.fieldByName = {}
|
|
310
|
+
self.fieldNames = []
|
|
311
|
+
print(self.recordPointer)
|
|
312
|
+
print(self.numRows)
|
|
313
|
+
print(self.cursor)
|
|
314
|
+
print("-----------------------------------------------------")
|
|
315
|
+
#print(self.cursor.description)
|
|
316
|
+
print(self.lstRecords)
|
|
317
|
+
print(self.recordPointer <= self.numRows)
|
|
318
|
+
print(self.recordPointer)
|
|
319
|
+
print(self.numRows)
|
|
320
|
+
print(type(self.recordPointer))
|
|
321
|
+
print(type(self.numRows))
|
|
322
|
+
columns = [column[0] for column in self.cursor.description]
|
|
323
|
+
self.fieldByName = (dict(zip(columns, self.lstRecords[self.recordPointer])))
|
|
324
|
+
#fieldNo = 0
|
|
325
|
+
#for cursorFieldname in self.cursor.description:
|
|
326
|
+
# self.fieldByName[cursorFieldname[0]] = self.lstRecords[(self.recordPointer-1)][fieldNo]
|
|
327
|
+
# self.fieldNames.append(cursorFieldname[0])
|
|
328
|
+
# fieldNo = fieldNo + 1
|
|
329
|
+
self.fields = self.fieldByName
|
|
330
|
+
self.recordPointer += 1
|
|
331
|
+
self.EOF = 0
|
|
332
|
+
else:
|
|
333
|
+
self.EOF = 1
|
|
334
|
+
'''
|
|
335
|
+
|
|
278
336
|
def first(self):
|
|
279
337
|
"""Move to the next record in the record set and loads the data into the fields property. Sets EOF at end of records."""
|
|
280
338
|
if(self.dbType == "MYSQL"):
|
|
@@ -323,13 +381,22 @@ class dbObjCursor:
|
|
|
323
381
|
self.recordPointer = 1
|
|
324
382
|
#print('progressExecute (fetchs all) time.time()-t0: ',str(round(time.time()-t0,3)),' seconds')
|
|
325
383
|
|
|
384
|
+
def jdbcExecute(self, prmSql):
|
|
385
|
+
self.cursor.execute(prmSql)
|
|
386
|
+
self.lstRecords = self.cursor.fetchall()
|
|
387
|
+
self.numRows = len(self.lstRecords)
|
|
388
|
+
self.numFields = len(self.cursor.description)
|
|
389
|
+
if(self.numRows > 0):
|
|
390
|
+
self.recordPointer = 1
|
|
391
|
+
|
|
326
392
|
class dbObjConnection:
|
|
327
393
|
"""
|
|
328
394
|
dbObjConnection is the database connection object. It is responsible for connecting to
|
|
329
395
|
the database. This object supports access to MySQL, Microsoft SQL Server, Oracle,
|
|
330
396
|
SQLite3, and Progress DataDirect.
|
|
331
397
|
|
|
332
|
-
prmDBType can be: MYSQL, MSSQL, ORACLE, SQLITE3, PROGRESS, or
|
|
398
|
+
prmDBType can be: MYSQL, MSSQL, ORACLE, SQLITE3, PROGRESS, API, or JDBC
|
|
399
|
+
|
|
333
400
|
"""
|
|
334
401
|
def __init__(self,
|
|
335
402
|
prmDBType="MYSQL",
|
|
@@ -341,6 +408,7 @@ class dbObjConnection:
|
|
|
341
408
|
envOracle={},
|
|
342
409
|
envProgress={},
|
|
343
410
|
driver='',
|
|
411
|
+
driverClass="",
|
|
344
412
|
prmApiBaseUrl="",
|
|
345
413
|
prmApiKey="",
|
|
346
414
|
prmApiKeyName="sk"):
|
|
@@ -355,6 +423,7 @@ class dbObjConnection:
|
|
|
355
423
|
self.reconnect_attempts = 0
|
|
356
424
|
self.using_pymysql = using_pymysql
|
|
357
425
|
self.drivers = lstLoadedDrivers
|
|
426
|
+
self.driverClass = driverClass
|
|
358
427
|
if(prmDBType == "API"):
|
|
359
428
|
self.apiBaseUrl = prmApiBaseUrl
|
|
360
429
|
self.apiKeyName = prmApiKeyName
|
|
@@ -416,6 +485,8 @@ class dbObjConnection:
|
|
|
416
485
|
return self.sqlite3Connect(prmDb)
|
|
417
486
|
elif(self.dbType == "PROGRESS"):
|
|
418
487
|
return self.progressConnect(prmHost, prmDb, prmUser, prmPass, prmPort)
|
|
488
|
+
elif(self.dbType == "JDBC"):
|
|
489
|
+
return self.jdbcConnect(prmHost, prmDb, prmUser, prmPass)
|
|
419
490
|
|
|
420
491
|
def setConnectSuccess(self):
|
|
421
492
|
self.reconnect_attempts = 0
|
|
@@ -506,6 +577,18 @@ class dbObjConnection:
|
|
|
506
577
|
self.setConnectSuccess()
|
|
507
578
|
return self.msgObj
|
|
508
579
|
|
|
580
|
+
def jdbcConnect(self, prmConnString, prmDriver, prmUser, prmPass):
|
|
581
|
+
try:
|
|
582
|
+
self.connHandle = jaydebeapi.connect(self.driverClass, prmConnString, [prmUser, prmPass], prmDriver)
|
|
583
|
+
if(self.connHandle):
|
|
584
|
+
self.setConnectSuccess()
|
|
585
|
+
else:
|
|
586
|
+
self.setConnectFail()
|
|
587
|
+
except Exception as e:
|
|
588
|
+
self.setConnectFail(e)
|
|
589
|
+
print(e)
|
|
590
|
+
return self.msgObj
|
|
591
|
+
|
|
509
592
|
def reconnect(self):
|
|
510
593
|
# https://dev.mysql.com/doc/refman/8.0/en/gone-away.html
|
|
511
594
|
mysql_lost_msg = '''
|
|
@@ -569,6 +652,8 @@ class dbObjConnection:
|
|
|
569
652
|
return self.progressGetCursor()
|
|
570
653
|
elif(self.dbType == "API"):
|
|
571
654
|
return self.apiGetCursor()
|
|
655
|
+
elif(self.dbType == "JDBC"):
|
|
656
|
+
return self.jdbcGetCursor()
|
|
572
657
|
|
|
573
658
|
def setCursorSuccess(self, cursor):
|
|
574
659
|
if cursor:
|
|
@@ -629,6 +714,14 @@ class dbObjConnection:
|
|
|
629
714
|
except Exception as e:
|
|
630
715
|
self.setCursorFail(e)
|
|
631
716
|
|
|
717
|
+
def jdbcGetCursor(self):
|
|
718
|
+
try:
|
|
719
|
+
cursor = dbObjCursor(self.connHandle, self.dbType)
|
|
720
|
+
self.setCursorSuccess(cursor)
|
|
721
|
+
return cursor
|
|
722
|
+
except Exception as e:
|
|
723
|
+
self.setCursorFail(e)
|
|
724
|
+
|
|
632
725
|
def disconnect(self):
|
|
633
726
|
"""Disconnect the connection handle to the database"""
|
|
634
727
|
if(self.dbType == "MYSQL"):
|
|
@@ -641,6 +734,8 @@ class dbObjConnection:
|
|
|
641
734
|
self.sqlite3Disconnect()
|
|
642
735
|
elif(self.dbType == "PROGRESS"):
|
|
643
736
|
self.progressDisconnect()
|
|
737
|
+
elif(self.dbType == "JDBC"):
|
|
738
|
+
self.jdbcDisconnect()
|
|
644
739
|
|
|
645
740
|
def mySqlDisconnect(self):
|
|
646
741
|
if self.connHandle and self.connHandle.open:
|
|
@@ -670,6 +765,11 @@ class dbObjConnection:
|
|
|
670
765
|
def apiDisconnect(self):
|
|
671
766
|
pass
|
|
672
767
|
|
|
768
|
+
def jdbcDisconnect(self):
|
|
769
|
+
if self.connHandle:
|
|
770
|
+
self.connHandle.close()
|
|
771
|
+
self.connHandle = None
|
|
772
|
+
|
|
673
773
|
def execute(self, prmSql, *args):
|
|
674
774
|
"""Execute the SQL and return a record set if applicable"""
|
|
675
775
|
if(self.dbType == "MYSQL"):
|
|
@@ -684,6 +784,8 @@ class dbObjConnection:
|
|
|
684
784
|
return self.progressExecute(prmSql)
|
|
685
785
|
if(self.dbType in ("API")):
|
|
686
786
|
return self.apiExecute(prmSql)
|
|
787
|
+
if(self.dbType in ("JDBC")):
|
|
788
|
+
return self.jdbcExecute(prmSql)
|
|
687
789
|
|
|
688
790
|
def fetchall(self, prmSql, *args):
|
|
689
791
|
"""Returns result set as a list of dictionaries"""
|
|
@@ -694,18 +796,33 @@ class dbObjConnection:
|
|
|
694
796
|
crsr.next()
|
|
695
797
|
return rset
|
|
696
798
|
|
|
799
|
+
|
|
697
800
|
def fetchone(self, prmSql, *args):
|
|
698
801
|
"""Returns a single row as a dictionary"""
|
|
699
802
|
crsr = self.execute( prmSql, *args )
|
|
700
803
|
dictRow = {} if crsr.EOF else crsr.fields
|
|
701
804
|
return dictRow
|
|
702
805
|
|
|
806
|
+
|
|
703
807
|
def fetchval(self, prmSql, *args):
|
|
704
808
|
"""Returns a single value"""
|
|
705
809
|
dictRow = self.fetchone( prmSql, *args )
|
|
706
810
|
listVals = list(dictRow.values())
|
|
707
811
|
return None if not listVals else listVals[0]
|
|
708
812
|
|
|
813
|
+
|
|
814
|
+
def fetchlistvals(self, prmSql, *args):
|
|
815
|
+
"""Returns a list of vals; if more than one key/column, returns a list of value tuples"""
|
|
816
|
+
listvals = []
|
|
817
|
+
rset = self.fetchall(prmSql, *args)
|
|
818
|
+
if not rset:
|
|
819
|
+
return []
|
|
820
|
+
for dictRow in rset:
|
|
821
|
+
vals = list(dictRow.values())[0] if len(dictRow.values())==1 else list(dictRow.values())
|
|
822
|
+
listvals.append( vals )
|
|
823
|
+
return listvals
|
|
824
|
+
|
|
825
|
+
|
|
709
826
|
def insert(self, table, prmDict, update_on_duplicate=False):
|
|
710
827
|
if update_on_duplicate:
|
|
711
828
|
keystr = ','.join(prmDict.keys())
|
|
@@ -818,7 +935,10 @@ class dbObjConnection:
|
|
|
818
935
|
def mySqlExecute(self, prmSql, *args):
|
|
819
936
|
mySqlCursor = self.getCursor()
|
|
820
937
|
try:
|
|
821
|
-
|
|
938
|
+
if args:
|
|
939
|
+
mySqlCursor.cursor.execute(prmSql, args)
|
|
940
|
+
else:
|
|
941
|
+
mySqlCursor.cursor.execute(prmSql)
|
|
822
942
|
self.msgObj.message = "SQL Executed: "+prmSql
|
|
823
943
|
self.msgObj.success = True
|
|
824
944
|
mySqlCursor.numRows = mySqlCursor.cursor.rowcount
|
|
@@ -937,7 +1057,6 @@ class dbObjConnection:
|
|
|
937
1057
|
try:
|
|
938
1058
|
# convert sqls to url safe version
|
|
939
1059
|
#sqls = requests.compat.quote_plus( prmSql )
|
|
940
|
-
#r = requests.post(self.apiBaseUrl + "/execute", data = {self.apiKeyName: self.apiKey, "sql": sqls})
|
|
941
1060
|
sqls = prmSql
|
|
942
1061
|
headers = {'Content-type':'application/json'}
|
|
943
1062
|
payload = {self.apiKeyName: self.apiKey, "sql": sqls}
|
|
@@ -976,6 +1095,24 @@ class dbObjConnection:
|
|
|
976
1095
|
apiCursor.success = False
|
|
977
1096
|
return apiCursor
|
|
978
1097
|
|
|
1098
|
+
def jdbcExecute(self, prmSql):
|
|
1099
|
+
jdbcCursor = self.getCursor()
|
|
1100
|
+
try:
|
|
1101
|
+
jdbcCursor.cursor.execute(prmSql)
|
|
1102
|
+
self.msgObj.message = "SQL Executed: "+prmSql
|
|
1103
|
+
self.msgObj.success = True
|
|
1104
|
+
except Exception as e:
|
|
1105
|
+
self.msgObj.message = "SQL Failed: "+prmSql+" - "+str(e)
|
|
1106
|
+
self.msgObj.success = False
|
|
1107
|
+
jdbcCursor.numFields = 0
|
|
1108
|
+
jdbcCursor.numRows = 0
|
|
1109
|
+
jdbcCursor.EOF = 1
|
|
1110
|
+
jdbcCursor.success = False
|
|
1111
|
+
print(self.msgObj.message)
|
|
1112
|
+
return jdbcCursor
|
|
1113
|
+
jdbcCursor.next()
|
|
1114
|
+
return jdbcCursor
|
|
1115
|
+
|
|
979
1116
|
def commit(self):
|
|
980
1117
|
if(self.dbType == "MYSQL"):
|
|
981
1118
|
self.connHandle.commit()
|
|
File without changes
|