dbobj3 0.3.0__tar.gz → 0.5.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.5.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.5.0"
|
|
20
20
|
commit = true
|
|
21
21
|
tag = true
|
|
22
22
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)"
|
|
@@ -21,12 +21,13 @@ Example:
|
|
|
21
21
|
rsServices.next()
|
|
22
22
|
|
|
23
23
|
"""
|
|
24
|
-
__version__ = "0.
|
|
24
|
+
__version__ = "0.5.0"
|
|
25
25
|
|
|
26
26
|
from sys import version as sys_version, exit
|
|
27
27
|
pyversion = sys_version[0:sys_version.find(' ')]
|
|
28
28
|
using_mysqlclient, using_pymysql = False, False
|
|
29
29
|
|
|
30
|
+
lstLoadedDrivers = []
|
|
30
31
|
try:
|
|
31
32
|
#raise ImportError
|
|
32
33
|
import MySQLdb
|
|
@@ -39,8 +40,9 @@ try:
|
|
|
39
40
|
# - For Python3.x use the fork MySQLdb
|
|
40
41
|
# - pip install mysqlclient ( developed by pymysql devs )
|
|
41
42
|
using_mysqlclient = True
|
|
43
|
+
lstLoadedDrivers.append({"MySQLdb": "Loaded (MySQL)"})
|
|
42
44
|
except ImportError:
|
|
43
|
-
|
|
45
|
+
lstLoadedDrivers.append({"MySQLdb": "Not Loaded (MySQL)"})
|
|
44
46
|
|
|
45
47
|
if not using_mysqlclient:
|
|
46
48
|
try:
|
|
@@ -55,40 +57,56 @@ if not using_mysqlclient:
|
|
|
55
57
|
#import pymysql.cursors
|
|
56
58
|
#import pymysql.converters
|
|
57
59
|
using_pymysql = True
|
|
60
|
+
lstLoadedDrivers.append({"pymysql": "Loaded (MySQL)"})
|
|
58
61
|
except ImportError:
|
|
59
62
|
#print('Python {0}: could neither import pymysql nor MySQLdb'.format(pyversion))
|
|
60
|
-
|
|
63
|
+
lstLoadedDrivers.append({"pymysql": "Not Loaded (MySQL)"})
|
|
61
64
|
#'''
|
|
62
65
|
|
|
63
66
|
try:
|
|
64
67
|
import pymssql
|
|
68
|
+
lstLoadedDrivers.append({"pymssql": "Loaded (Microsoft SQL Server)"})
|
|
65
69
|
except ImportError:
|
|
66
70
|
#print('could not import pymssql')
|
|
67
|
-
|
|
71
|
+
lstLoadedDrivers.append({"pymssql": "Not Loaded (Microsoft SQL Server)"})
|
|
68
72
|
|
|
69
73
|
try:
|
|
70
74
|
import cx_Oracle
|
|
75
|
+
lstLoadedDrivers.append({"cx_Oracle": "Loaded (Oracle)"})
|
|
71
76
|
except ImportError:
|
|
72
77
|
#print('could not import cx_Oracle')
|
|
73
|
-
|
|
78
|
+
lstLoadedDrivers.append({"cx_Oracle": "Not Loaded (Oracle)"})
|
|
74
79
|
|
|
75
80
|
try:
|
|
76
81
|
import sqlite3
|
|
82
|
+
lstLoadedDrivers.append({"sqlite3": "Loaded (Sqlite3)"})
|
|
77
83
|
except ImportError:
|
|
78
84
|
#print('could not import sqlite3')
|
|
79
|
-
|
|
85
|
+
lstLoadedDrivers.append({"sqlite3": "Not Loaded (Sqlite3)"})
|
|
80
86
|
|
|
81
87
|
try:
|
|
82
88
|
import pyodbc
|
|
89
|
+
lstLoadedDrivers.append({"pyodbc": "Loaded (ODBC)"})
|
|
83
90
|
except ImportError:
|
|
84
91
|
#print('could not import pyodbc')
|
|
85
|
-
|
|
92
|
+
lstLoadedDrivers.append({"pyodbc": "Not Loaded (ODBC)"})
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
import requests
|
|
96
|
+
lstLoadedDrivers.append({"requests": "Loaded (API)"})
|
|
97
|
+
except ImportError:
|
|
98
|
+
#print('could not import pyodbc')
|
|
99
|
+
lstLoadedDrivers.append({"requests": "Not Loaded (API)"})
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
import json
|
|
103
|
+
except ImportError:
|
|
104
|
+
print(str(ImportError))
|
|
86
105
|
|
|
87
106
|
import os, getpass, time
|
|
88
107
|
currUser = getpass.getuser()
|
|
89
108
|
homeDir = '/root' if currUser == 'root' else '/home/{u}'.format(u=currUser)
|
|
90
109
|
|
|
91
|
-
|
|
92
110
|
class dbConnMessage:
|
|
93
111
|
"""
|
|
94
112
|
The dbConnMessage is an object that is returned in response to a dbObjConnection. It has two
|
|
@@ -100,7 +118,6 @@ class dbConnMessage:
|
|
|
100
118
|
self.success = False
|
|
101
119
|
self.message = ""
|
|
102
120
|
|
|
103
|
-
|
|
104
121
|
class dbObjCursor:
|
|
105
122
|
"""
|
|
106
123
|
Database cursor object controls the cursor connected to a database. Multiple cursors
|
|
@@ -118,7 +135,6 @@ class dbObjCursor:
|
|
|
118
135
|
self.dbType = prmDBType.upper()
|
|
119
136
|
self.create(self.dbType)
|
|
120
137
|
|
|
121
|
-
|
|
122
138
|
def __del__(self):
|
|
123
139
|
if(self.dbType == "MYSQL"):
|
|
124
140
|
try:
|
|
@@ -127,7 +143,6 @@ class dbObjCursor:
|
|
|
127
143
|
except:
|
|
128
144
|
pass
|
|
129
145
|
|
|
130
|
-
|
|
131
146
|
def create(self, prmDBType="MYSQL"):
|
|
132
147
|
if(prmDBType=="MYSQL"):
|
|
133
148
|
self.createMySql()
|
|
@@ -139,35 +154,33 @@ class dbObjCursor:
|
|
|
139
154
|
self.createSqlite3()
|
|
140
155
|
elif(prmDBType=="PROGRESS"):
|
|
141
156
|
self.createProgress()
|
|
142
|
-
|
|
157
|
+
elif(prmDBType=="API"):
|
|
158
|
+
self.createAPI()
|
|
143
159
|
|
|
144
160
|
def createMySql(self):
|
|
145
161
|
self.cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
|
|
146
162
|
|
|
147
|
-
|
|
148
163
|
def createMsSql(self):
|
|
149
164
|
self.cursor = self.connection.cursor(as_dict=True)
|
|
150
165
|
|
|
151
|
-
|
|
152
166
|
def createOracle(self):
|
|
153
167
|
self.cursor = self.connection.cursor()
|
|
154
168
|
|
|
155
|
-
|
|
156
169
|
def createSqlite3(self):
|
|
157
170
|
self.cursor = self.connection.cursor()
|
|
158
171
|
|
|
159
|
-
|
|
160
172
|
def createProgress(self):
|
|
161
173
|
self.cursor = self.connection.cursor()
|
|
162
174
|
#for ln in [ i for i in dir(self.cursor) if not i[0]=='_']:
|
|
163
175
|
# print(ln)
|
|
164
176
|
|
|
177
|
+
def createAPI(self):
|
|
178
|
+
self.lstRecords = []
|
|
165
179
|
|
|
166
180
|
def moveNext(self):
|
|
167
181
|
"""Same as next"""
|
|
168
182
|
self.next()
|
|
169
183
|
|
|
170
|
-
|
|
171
184
|
def next(self):
|
|
172
185
|
"""Move to the next record in the record set and loads the data into the fields property. Sets EOF at end of records."""
|
|
173
186
|
if(self.dbType == "MYSQL"):
|
|
@@ -180,7 +193,8 @@ class dbObjCursor:
|
|
|
180
193
|
self.sqlite3Next()
|
|
181
194
|
elif(self.dbType == "PROGRESS"):
|
|
182
195
|
self.progressNext()
|
|
183
|
-
|
|
196
|
+
elif(self.dbType == "API"):
|
|
197
|
+
self.apiNext()
|
|
184
198
|
|
|
185
199
|
def mySqlNext(self):
|
|
186
200
|
resultSet = self.cursor.fetchone()
|
|
@@ -193,7 +207,6 @@ class dbObjCursor:
|
|
|
193
207
|
self.fields = self.fieldByName
|
|
194
208
|
self.EOF = 1
|
|
195
209
|
|
|
196
|
-
|
|
197
210
|
def msSqlNext(self):
|
|
198
211
|
try:
|
|
199
212
|
resultSet = self.cursor.fetchone()
|
|
@@ -207,7 +220,6 @@ class dbObjCursor:
|
|
|
207
220
|
else:
|
|
208
221
|
self.EOF = 1
|
|
209
222
|
|
|
210
|
-
|
|
211
223
|
def oracleNext(self):
|
|
212
224
|
if(self.recordPointer <= self.numRows):
|
|
213
225
|
self.fieldByName = {}
|
|
@@ -223,7 +235,6 @@ class dbObjCursor:
|
|
|
223
235
|
else:
|
|
224
236
|
self.EOF = 1
|
|
225
237
|
|
|
226
|
-
|
|
227
238
|
def sqlite3Next(self):
|
|
228
239
|
if(self.recordPointer <= self.numRows):
|
|
229
240
|
self.fieldByName = {}
|
|
@@ -239,7 +250,6 @@ class dbObjCursor:
|
|
|
239
250
|
else:
|
|
240
251
|
self.EOF = 1
|
|
241
252
|
|
|
242
|
-
|
|
243
253
|
def progressNext(self):
|
|
244
254
|
if(self.recordPointer <= self.numRows):
|
|
245
255
|
self.fieldByName = {}
|
|
@@ -255,18 +265,25 @@ class dbObjCursor:
|
|
|
255
265
|
else:
|
|
256
266
|
self.EOF = 1
|
|
257
267
|
|
|
268
|
+
def apiNext(self):
|
|
269
|
+
if(self.recordPointer < self.numRows):
|
|
270
|
+
self.fieldNames = self.lstRecords[self.recordPointer].keys()
|
|
271
|
+
self.fieldByName = self.lstRecords[self.recordPointer]
|
|
272
|
+
self.fields = self.fieldByName
|
|
273
|
+
self.recordPointer += 1
|
|
274
|
+
self.EOF = 0
|
|
275
|
+
else:
|
|
276
|
+
self.EOF = 1
|
|
258
277
|
|
|
259
278
|
def first(self):
|
|
260
279
|
"""Move to the next record in the record set and loads the data into the fields property. Sets EOF at end of records."""
|
|
261
280
|
if(self.dbType == "MYSQL"):
|
|
262
281
|
self.mySqlFirst()
|
|
263
282
|
|
|
264
|
-
|
|
265
283
|
def mySqlFirst(self):
|
|
266
284
|
resultSet = self.cursor.scroll(0,'absolute')
|
|
267
285
|
self.mySqlNext()
|
|
268
286
|
|
|
269
|
-
|
|
270
287
|
def oracleExecute(self, prmSql):
|
|
271
288
|
"""
|
|
272
289
|
Oracle had to be handled differently due to cursor.rowcount failing. This method is called
|
|
@@ -280,7 +297,6 @@ class dbObjCursor:
|
|
|
280
297
|
if(self.numRows > 0):
|
|
281
298
|
self.recordPointer = 1
|
|
282
299
|
|
|
283
|
-
|
|
284
300
|
def sqlite3Execute(self, prmSql):
|
|
285
301
|
"""
|
|
286
302
|
Sqlite3Execute method is called transparently by dbObjConnection.execute and fetches all records at once where the other
|
|
@@ -293,7 +309,6 @@ class dbObjCursor:
|
|
|
293
309
|
if(self.numRows > 0):
|
|
294
310
|
self.recordPointer = 1
|
|
295
311
|
|
|
296
|
-
|
|
297
312
|
def progressExecute(self, prmSql):
|
|
298
313
|
"""
|
|
299
314
|
progressExecute method is called transparently by dbObjConnection.execute and fetches all records at once where the other
|
|
@@ -308,25 +323,27 @@ class dbObjCursor:
|
|
|
308
323
|
self.recordPointer = 1
|
|
309
324
|
#print('progressExecute (fetchs all) time.time()-t0: ',str(round(time.time()-t0,3)),' seconds')
|
|
310
325
|
|
|
311
|
-
|
|
312
|
-
|
|
313
326
|
class dbObjConnection:
|
|
314
327
|
"""
|
|
315
328
|
dbObjConnection is the database connection object. It is responsible for connecting to
|
|
316
329
|
the database. This object supports access to MySQL, Microsoft SQL Server, Oracle,
|
|
317
330
|
SQLite3, and Progress DataDirect.
|
|
318
331
|
|
|
319
|
-
prmDBType can be: MYSQL, MSSQL, ORACLE, SQLITE3, or
|
|
332
|
+
prmDBType can be: MYSQL, MSSQL, ORACLE, SQLITE3, PROGRESS, or API
|
|
320
333
|
"""
|
|
321
334
|
def __init__(self,
|
|
322
335
|
prmDBType="MYSQL",
|
|
323
336
|
prmHost="localhost",
|
|
324
337
|
prmDb="",
|
|
325
338
|
prmUser="",
|
|
326
|
-
prmPass="",
|
|
339
|
+
prmPass="",
|
|
340
|
+
prmPort=3306,
|
|
327
341
|
envOracle={},
|
|
328
342
|
envProgress={},
|
|
329
|
-
driver=''
|
|
343
|
+
driver='',
|
|
344
|
+
prmApiBaseUrl="",
|
|
345
|
+
prmApiKey="",
|
|
346
|
+
prmApiKeyName="sk"):
|
|
330
347
|
self.set_env( envOracle=envOracle, envProgress=envProgress, driver=driver )
|
|
331
348
|
self.EOF = 1
|
|
332
349
|
self.connHandle = 0
|
|
@@ -336,16 +353,21 @@ class dbObjConnection:
|
|
|
336
353
|
self.autoreconnect = True if self.dbType == "MYSQL" else False
|
|
337
354
|
self.reconnect_max = 2
|
|
338
355
|
self.reconnect_attempts = 0
|
|
339
|
-
self.using_pymysql = using_pymysql
|
|
340
|
-
self.
|
|
341
|
-
if(
|
|
356
|
+
self.using_pymysql = using_pymysql
|
|
357
|
+
self.drivers = lstLoadedDrivers
|
|
358
|
+
if(prmDBType == "API"):
|
|
359
|
+
self.apiBaseUrl = prmApiBaseUrl
|
|
360
|
+
self.apiKeyName = prmApiKeyName
|
|
361
|
+
self.apiKey = prmApiKey
|
|
342
362
|
self.connect()
|
|
343
|
-
|
|
363
|
+
else:
|
|
364
|
+
self.host, self.db, self.user, self.passwd, self.port = prmHost, prmDb, prmUser, prmPass, prmPort
|
|
365
|
+
if( self.dbType and self.host and self.db and self.user and self.passwd and self.port ):
|
|
366
|
+
self.connect()
|
|
344
367
|
|
|
345
368
|
def __del__(self):
|
|
346
369
|
self.close_connection()
|
|
347
370
|
|
|
348
|
-
|
|
349
371
|
def set_env(self, envOracle={}, envProgress={}, driver={}):
|
|
350
372
|
default_envOracle = { 'LD_LIBRARY_PATH': '/usr/lib/oracle/instantclient_12_2/',
|
|
351
373
|
'ORACLE_HOME': '/usr/lib/oracle/instantclient_12_2/',
|
|
@@ -365,7 +387,6 @@ class dbObjConnection:
|
|
|
365
387
|
os.putenv( env_var, env_val )
|
|
366
388
|
os.environ[ env_var ] = env_val
|
|
367
389
|
|
|
368
|
-
|
|
369
390
|
def close_connection(self):
|
|
370
391
|
try:
|
|
371
392
|
if self.connHandle and not( isinstance(self.connHandle, int) ):
|
|
@@ -375,37 +396,36 @@ class dbObjConnection:
|
|
|
375
396
|
except Exception as e:
|
|
376
397
|
print(str(e))
|
|
377
398
|
|
|
378
|
-
|
|
379
399
|
def connect(self, prmHost="", prmDb="", prmUser="", prmPass="", prmPort=3306):
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
400
|
+
if(self.dbType == "API"):
|
|
401
|
+
return self.apiConnect()
|
|
402
|
+
else:
|
|
403
|
+
prmHost = prmHost or self.host
|
|
404
|
+
prmDb = prmDb or self.db
|
|
405
|
+
prmUser = prmUser or self.user
|
|
406
|
+
prmPass = prmPass or self.passwd
|
|
407
|
+
prmPort = prmPort or self.port
|
|
408
|
+
self.host, self.db, self.user, self.passwd, self.port = prmHost, prmDb, prmUser, prmPass, prmPort
|
|
409
|
+
if(self.dbType == "MYSQL"):
|
|
410
|
+
return self.mySqlConnect(prmHost, prmDb, prmUser, prmPass, prmPort)
|
|
411
|
+
elif(self.dbType == "MSSQL"):
|
|
412
|
+
return self.msSqlConnect(prmHost, prmDb, prmUser, prmPass)
|
|
413
|
+
elif(self.dbType == "ORACLE"):
|
|
414
|
+
return self.oracleConnect(prmUser, prmPass, prmDb)
|
|
415
|
+
elif(self.dbType == "SQLITE" or self.dbType == "SQLITE3"):
|
|
416
|
+
return self.sqlite3Connect(prmDb)
|
|
417
|
+
elif(self.dbType == "PROGRESS"):
|
|
418
|
+
return self.progressConnect(prmHost, prmDb, prmUser, prmPass, prmPort)
|
|
397
419
|
|
|
398
420
|
def setConnectSuccess(self):
|
|
399
421
|
self.reconnect_attempts = 0
|
|
400
422
|
self.msgObj.message = "Connected to {0} Database okay.".format(self.dbType)
|
|
401
423
|
self.msgObj.success = True
|
|
402
424
|
|
|
403
|
-
|
|
404
425
|
def setConnectFail(self, msgException=""):
|
|
405
426
|
self.msgObj.message += " - Connection to {0} Database Failed. {1}".format(self.dbType, msgException)
|
|
406
427
|
self.msgObj.success = False
|
|
407
428
|
|
|
408
|
-
|
|
409
429
|
def mySqlConnect(self, prmHost, prmDb, prmUser, prmPass, prmPort=3306):
|
|
410
430
|
try:
|
|
411
431
|
self.connHandle = MySQLdb.connect(host=prmHost,db=prmDb,user=prmUser,passwd=prmPass,port=prmPort)
|
|
@@ -418,7 +438,6 @@ class dbObjConnection:
|
|
|
418
438
|
self.setConnectFail(e)
|
|
419
439
|
return self.msgObj
|
|
420
440
|
|
|
421
|
-
|
|
422
441
|
def msSqlConnect(self, prmHost, prmDb, prmUser, prmPass):
|
|
423
442
|
try:
|
|
424
443
|
self.connHandle = pymssql.connect(prmHost, prmUser, prmPass, prmDb)
|
|
@@ -431,7 +450,6 @@ class dbObjConnection:
|
|
|
431
450
|
self.setConnectFail(e)
|
|
432
451
|
return self.msgObj
|
|
433
452
|
|
|
434
|
-
|
|
435
453
|
def oracleConnect(self, prmUser, prmPass, prmTns):
|
|
436
454
|
try:
|
|
437
455
|
self.connHandle = cx_Oracle.connect(prmUser, prmPass, prmTns)
|
|
@@ -443,7 +461,6 @@ class dbObjConnection:
|
|
|
443
461
|
self.setConnectFail(e)
|
|
444
462
|
return self.msgObj
|
|
445
463
|
|
|
446
|
-
|
|
447
464
|
def sqlite3Connect(self, prmDb):
|
|
448
465
|
try:
|
|
449
466
|
self.connHandle = sqlite3.connect(prmDb)
|
|
@@ -456,7 +473,6 @@ class dbObjConnection:
|
|
|
456
473
|
self.setConnectFail(e)
|
|
457
474
|
return self.msgObj
|
|
458
475
|
|
|
459
|
-
|
|
460
476
|
def progressConnect(self, prmHost, prmDb, prmUser, prmPass, prmPort=35078, envProgress={}, driver=None):
|
|
461
477
|
try:
|
|
462
478
|
driver = driver or self.driver
|
|
@@ -483,6 +499,12 @@ class dbObjConnection:
|
|
|
483
499
|
|
|
484
500
|
return self.msgObj
|
|
485
501
|
|
|
502
|
+
def apiConnect(self):
|
|
503
|
+
if(self.apiBaseUrl == "" or self.apiKey == ""):
|
|
504
|
+
self.setConnectFail("API URL or Key missing")
|
|
505
|
+
else:
|
|
506
|
+
self.setConnectSuccess()
|
|
507
|
+
return self.msgObj
|
|
486
508
|
|
|
487
509
|
def reconnect(self):
|
|
488
510
|
# https://dev.mysql.com/doc/refman/8.0/en/gone-away.html
|
|
@@ -534,7 +556,6 @@ class dbObjConnection:
|
|
|
534
556
|
print('Connection to {0} Restored.'.format(self.dbType))
|
|
535
557
|
return self.msgObj
|
|
536
558
|
|
|
537
|
-
|
|
538
559
|
def getCursor(self):
|
|
539
560
|
if(self.dbType == "MYSQL"):
|
|
540
561
|
return self.mySqlGetCursor()
|
|
@@ -546,7 +567,8 @@ class dbObjConnection:
|
|
|
546
567
|
return self.sqlite3GetCursor()
|
|
547
568
|
elif(self.dbType == "PROGRESS"):
|
|
548
569
|
return self.progressGetCursor()
|
|
549
|
-
|
|
570
|
+
elif(self.dbType == "API"):
|
|
571
|
+
return self.apiGetCursor()
|
|
550
572
|
|
|
551
573
|
def setCursorSuccess(self, cursor):
|
|
552
574
|
if cursor:
|
|
@@ -555,12 +577,10 @@ class dbObjConnection:
|
|
|
555
577
|
else:
|
|
556
578
|
self.setCursorFail()
|
|
557
579
|
|
|
558
|
-
|
|
559
580
|
def setCursorFail(self,msgException):
|
|
560
581
|
self.msgObj.message = "Exception Getting {0} Cursor: {1}".format(self.dbType,msgException)
|
|
561
582
|
self.msgObj.success = False
|
|
562
583
|
|
|
563
|
-
|
|
564
584
|
def mySqlGetCursor(self):
|
|
565
585
|
try:
|
|
566
586
|
cursor = dbObjCursor(self.connHandle, self.dbType)
|
|
@@ -569,7 +589,6 @@ class dbObjConnection:
|
|
|
569
589
|
except Exception as e:
|
|
570
590
|
self.setCursorFail(e)
|
|
571
591
|
|
|
572
|
-
|
|
573
592
|
def mssqlGetCursor(self):
|
|
574
593
|
try:
|
|
575
594
|
cursor = dbObjCursor(self.connHandle, self.dbType)
|
|
@@ -578,7 +597,6 @@ class dbObjConnection:
|
|
|
578
597
|
except Exception as e:
|
|
579
598
|
self.setCursorFail(e)
|
|
580
599
|
|
|
581
|
-
|
|
582
600
|
def oracleGetCursor(self):
|
|
583
601
|
try:
|
|
584
602
|
cursor = dbObjCursor(self.connHandle, self.dbType)
|
|
@@ -587,7 +605,6 @@ class dbObjConnection:
|
|
|
587
605
|
except Exception as e:
|
|
588
606
|
self.setCursorFail(e)
|
|
589
607
|
|
|
590
|
-
|
|
591
608
|
def sqlite3GetCursor(self):
|
|
592
609
|
try:
|
|
593
610
|
cursor = dbObjCursor(self.connHandle, self.dbType)
|
|
@@ -596,7 +613,6 @@ class dbObjConnection:
|
|
|
596
613
|
except Exception as e:
|
|
597
614
|
self.setCursorFail(e)
|
|
598
615
|
|
|
599
|
-
|
|
600
616
|
def progressGetCursor(self):
|
|
601
617
|
try:
|
|
602
618
|
cursor = dbObjCursor(self.connHandle, self.dbType)
|
|
@@ -605,6 +621,13 @@ class dbObjConnection:
|
|
|
605
621
|
except Exception as e:
|
|
606
622
|
self.setCursorFail(e)
|
|
607
623
|
|
|
624
|
+
def apiGetCursor(self):
|
|
625
|
+
try:
|
|
626
|
+
cursor = dbObjCursor(None, self.dbType)
|
|
627
|
+
self.setCursorSuccess(cursor)
|
|
628
|
+
return cursor
|
|
629
|
+
except Exception as e:
|
|
630
|
+
self.setCursorFail(e)
|
|
608
631
|
|
|
609
632
|
def disconnect(self):
|
|
610
633
|
"""Disconnect the connection handle to the database"""
|
|
@@ -619,36 +642,33 @@ class dbObjConnection:
|
|
|
619
642
|
elif(self.dbType == "PROGRESS"):
|
|
620
643
|
self.progressDisconnect()
|
|
621
644
|
|
|
622
|
-
|
|
623
645
|
def mySqlDisconnect(self):
|
|
624
646
|
if self.connHandle and self.connHandle.open:
|
|
625
647
|
self.connHandle.close()
|
|
626
648
|
self.connHandle = None
|
|
627
649
|
|
|
628
|
-
|
|
629
650
|
def msSqlDisconnect(self):
|
|
630
651
|
if self.connHandle and self.connHandle.open:
|
|
631
652
|
self.connHandle.close()
|
|
632
653
|
self.connHandle = None
|
|
633
654
|
|
|
634
|
-
|
|
635
655
|
def oracleDisconnect(self):
|
|
636
656
|
if self.connHandle:
|
|
637
657
|
self.connHandle.close()
|
|
638
658
|
self.connHandle = None
|
|
639
659
|
|
|
640
|
-
|
|
641
660
|
def sqlite3Disconnect(self):
|
|
642
661
|
if self.connHandle and self.connHandle.open:
|
|
643
662
|
self.connHandle.close()
|
|
644
663
|
self.connHandle = None
|
|
645
664
|
|
|
646
|
-
|
|
647
665
|
def progressDisconnect(self):
|
|
648
666
|
if self.connHandle:
|
|
649
667
|
self.connHandle.close()
|
|
650
668
|
self.connHandle = None
|
|
651
669
|
|
|
670
|
+
def apiDisconnect(self):
|
|
671
|
+
pass
|
|
652
672
|
|
|
653
673
|
def execute(self, prmSql, *args):
|
|
654
674
|
"""Execute the SQL and return a record set if applicable"""
|
|
@@ -662,6 +682,8 @@ class dbObjConnection:
|
|
|
662
682
|
return self.sqlite3Execute(prmSql)
|
|
663
683
|
if(self.dbType in ("PROGRESS")):
|
|
664
684
|
return self.progressExecute(prmSql)
|
|
685
|
+
if(self.dbType in ("API")):
|
|
686
|
+
return self.apiExecute(prmSql)
|
|
665
687
|
|
|
666
688
|
|
|
667
689
|
def fetchall(self, prmSql, *args):
|
|
@@ -688,6 +710,21 @@ class dbObjConnection:
|
|
|
688
710
|
return None if not listVals else listVals[0]
|
|
689
711
|
|
|
690
712
|
|
|
713
|
+
def fetchlistvals(self, prmSql, *args):
|
|
714
|
+
"""Returns a list of vals; if more than one key/column, returns a list of value tuples"""
|
|
715
|
+
listvals = []
|
|
716
|
+
rset = self.fetchall(prmSql, *args)
|
|
717
|
+
if not rset:
|
|
718
|
+
return []
|
|
719
|
+
keys = list(rset[0].keys())
|
|
720
|
+
for dictRow in rset:
|
|
721
|
+
if len(keys) == 1:
|
|
722
|
+
listvals.append( dictRow.get(keys[0]) )
|
|
723
|
+
else:
|
|
724
|
+
listvals.append( tuple( dictRow.get(k) for k in keys ) )
|
|
725
|
+
return listvals
|
|
726
|
+
|
|
727
|
+
|
|
691
728
|
def insert(self, table, prmDict, update_on_duplicate=False):
|
|
692
729
|
if update_on_duplicate:
|
|
693
730
|
keystr = ','.join(prmDict.keys())
|
|
@@ -704,14 +741,12 @@ class dbObjConnection:
|
|
|
704
741
|
strSql = "INSERT INTO {table} ({keystr}) VALUES ({valstr})".format(table=table,keystr=keystr,valstr=valstr)
|
|
705
742
|
return self.execute(strSql, *args)
|
|
706
743
|
|
|
707
|
-
|
|
708
744
|
def updatedict(self, table, unique_column, unique_value, prmDict):
|
|
709
745
|
setstr = ",".join(["{k}=%s".format(k=k) for k in prmDict.keys()])
|
|
710
746
|
args = tuple(prmDict.values())
|
|
711
747
|
strSql = "UPDATE {table} SET {setstr} WHERE {unique_column} = {unique_value}".format(table=table,setstr=setstr,unique_column=unique_column,unique_value=unique_value)
|
|
712
748
|
return self.execute(strSql, *args)
|
|
713
749
|
|
|
714
|
-
|
|
715
750
|
def ping(self, reconnect=True):
|
|
716
751
|
if(self.dbType == "MYSQL"):
|
|
717
752
|
self.mySqlPing()
|
|
@@ -732,7 +767,6 @@ class dbObjConnection:
|
|
|
732
767
|
pass
|
|
733
768
|
self.progressPing()
|
|
734
769
|
|
|
735
|
-
|
|
736
770
|
def mySqlPing(self, reconnect=True):
|
|
737
771
|
"""
|
|
738
772
|
Check if the server is alive.
|
|
@@ -771,7 +805,6 @@ class dbObjConnection:
|
|
|
771
805
|
else:
|
|
772
806
|
raise Exception
|
|
773
807
|
|
|
774
|
-
|
|
775
808
|
def setMySqlExecuteFail(self, mySqlCursor, prmSql, e, *args):
|
|
776
809
|
self.msgObj.success = False
|
|
777
810
|
prmSql += '' if not args else ' ({0}) '.format( repr(args) )
|
|
@@ -801,7 +834,6 @@ class dbObjConnection:
|
|
|
801
834
|
finally:
|
|
802
835
|
return mySqlCursor
|
|
803
836
|
|
|
804
|
-
|
|
805
837
|
def mySqlExecute(self, prmSql, *args):
|
|
806
838
|
mySqlCursor = self.getCursor()
|
|
807
839
|
try:
|
|
@@ -838,7 +870,6 @@ class dbObjConnection:
|
|
|
838
870
|
mySqlCursor = self.setMySqlExecuteSuccess(mySqlCursor, prmSql, *args)
|
|
839
871
|
return mySqlCursor
|
|
840
872
|
|
|
841
|
-
|
|
842
873
|
def msSqlExecute(self, prmSql):
|
|
843
874
|
msSqlCursor = self.getCursor()
|
|
844
875
|
try:
|
|
@@ -857,7 +888,6 @@ class dbObjConnection:
|
|
|
857
888
|
msSqlCursor.next()
|
|
858
889
|
return msSqlCursor
|
|
859
890
|
|
|
860
|
-
|
|
861
891
|
def oracleExecute(self, prmSql):
|
|
862
892
|
oracleCursor = self.getCursor()
|
|
863
893
|
try:
|
|
@@ -879,7 +909,6 @@ class dbObjConnection:
|
|
|
879
909
|
oracleCursor.EOF = 1
|
|
880
910
|
return oracleCursor
|
|
881
911
|
|
|
882
|
-
|
|
883
912
|
def sqlite3Execute(self, prmSql):
|
|
884
913
|
sqliteCursor = self.getCursor()
|
|
885
914
|
try:
|
|
@@ -900,7 +929,6 @@ class dbObjConnection:
|
|
|
900
929
|
sqliteCursor.EOF = 1
|
|
901
930
|
return sqliteCursor
|
|
902
931
|
|
|
903
|
-
|
|
904
932
|
def progressExecute(self, prmSql):
|
|
905
933
|
progressCursor = self.getCursor()
|
|
906
934
|
try:
|
|
@@ -922,12 +950,54 @@ class dbObjConnection:
|
|
|
922
950
|
progressCursor.EOF = 1
|
|
923
951
|
return progressCursor
|
|
924
952
|
|
|
953
|
+
def apiExecute(self, prmSql):
|
|
954
|
+
apiCursor = self.getCursor()
|
|
955
|
+
apiCursor.success = False
|
|
956
|
+
try:
|
|
957
|
+
# convert sqls to url safe version
|
|
958
|
+
#sqls = requests.compat.quote_plus( prmSql )
|
|
959
|
+
sqls = prmSql
|
|
960
|
+
headers = {'Content-type':'application/json'}
|
|
961
|
+
payload = {self.apiKeyName: self.apiKey, "sql": sqls}
|
|
962
|
+
r = requests.post(self.apiBaseUrl + "/execute", data=json.dumps(payload), headers=headers)
|
|
963
|
+
#print(r.request.body)
|
|
964
|
+
#print(r.request.headers)
|
|
965
|
+
if(r.status_code == requests.codes.ok):
|
|
966
|
+
retVal = r.json()
|
|
967
|
+
#print(retVal)
|
|
968
|
+
if(retVal["error"] == 0):
|
|
969
|
+
apiCursor.lstRecords = retVal["data"]
|
|
970
|
+
apiCursor.numRows = len(apiCursor.lstRecords)
|
|
971
|
+
if(apiCursor.numRows > 0):
|
|
972
|
+
apiCursor.numFields = len(apiCursor.lstRecords[0].keys())
|
|
973
|
+
apiCursor.EOF = 0
|
|
974
|
+
self.lastInsId = retVal["message"]
|
|
975
|
+
apiCursor.next()
|
|
976
|
+
else:
|
|
977
|
+
apiCursor.numFields = 0
|
|
978
|
+
apiCursor.EOF = 1
|
|
979
|
+
apiCursor.success = True
|
|
980
|
+
self.msgObj.message = "SQL Executed: "+prmSql
|
|
981
|
+
self.msgObj.success = True
|
|
982
|
+
else:
|
|
983
|
+
self.msgObj.message = "SQL Failed: "+str(retVal["message"])
|
|
984
|
+
self.msgObj.success = False
|
|
985
|
+
else:
|
|
986
|
+
self.msgObj.message = "SQL Failed: "+str(r.status_code)
|
|
987
|
+
self.msgObj.success = False
|
|
988
|
+
except Exception as e:
|
|
989
|
+
self.msgObj.message = "SQL Failed: "+prmSql+" - "+str(e)
|
|
990
|
+
self.msgObj.success = False
|
|
991
|
+
apiCursor.numFields = 0
|
|
992
|
+
apiCursor.numRows = 0
|
|
993
|
+
apiCursor.EOF = 1
|
|
994
|
+
apiCursor.success = False
|
|
995
|
+
return apiCursor
|
|
925
996
|
|
|
926
997
|
def commit(self):
|
|
927
998
|
if(self.dbType == "MYSQL"):
|
|
928
999
|
self.connHandle.commit()
|
|
929
1000
|
|
|
930
|
-
|
|
931
1001
|
if __name__ == '__main__':
|
|
932
1002
|
import time, pprint
|
|
933
1003
|
pp = pprint.PrettyPrinter(indent=4, width=80).pprint
|
|
@@ -940,7 +1010,6 @@ if __name__ == '__main__':
|
|
|
940
1010
|
else:
|
|
941
1011
|
return input(prompt,*args,**kwargs)
|
|
942
1012
|
|
|
943
|
-
|
|
944
1013
|
def dbtest():
|
|
945
1014
|
dbhost = getInput( "MySQL Hostname: " )
|
|
946
1015
|
dbname = getInput( "MySQL Database Name: ")
|
|
@@ -952,7 +1021,6 @@ if __name__ == '__main__':
|
|
|
952
1021
|
print( "message: {v}".format(v=result.message) )
|
|
953
1022
|
return odb if result.success else None
|
|
954
1023
|
|
|
955
|
-
|
|
956
1024
|
def sqltest(dbConn=None,sqls=''):
|
|
957
1025
|
sqls = sqls or getInput( "\nEnter SQL Statement: ")
|
|
958
1026
|
t0 = time.time()
|
|
@@ -971,7 +1039,6 @@ if __name__ == '__main__':
|
|
|
971
1039
|
print('\n')
|
|
972
1040
|
return sqls, rset
|
|
973
1041
|
|
|
974
|
-
|
|
975
1042
|
def run_test():
|
|
976
1043
|
odb = None
|
|
977
1044
|
print("<enter> for yes or 'n' for no\n")
|
|
@@ -1022,7 +1089,5 @@ if __name__ == '__main__':
|
|
|
1022
1089
|
odb.autoreconnect = True
|
|
1023
1090
|
return odb
|
|
1024
1091
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
1092
|
# odb will be the interactively instantiated dbObj connection
|
|
1028
1093
|
odb = run_test()
|
|
File without changes
|