dbobj3 0.3.0__tar.gz → 0.4.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.4.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.4.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.4.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,7 +682,8 @@ class dbObjConnection:
|
|
|
662
682
|
return self.sqlite3Execute(prmSql)
|
|
663
683
|
if(self.dbType in ("PROGRESS")):
|
|
664
684
|
return self.progressExecute(prmSql)
|
|
665
|
-
|
|
685
|
+
if(self.dbType in ("API")):
|
|
686
|
+
return self.apiExecute(prmSql)
|
|
666
687
|
|
|
667
688
|
def fetchall(self, prmSql, *args):
|
|
668
689
|
"""Returns result set as a list of dictionaries"""
|
|
@@ -673,21 +694,18 @@ class dbObjConnection:
|
|
|
673
694
|
crsr.next()
|
|
674
695
|
return rset
|
|
675
696
|
|
|
676
|
-
|
|
677
697
|
def fetchone(self, prmSql, *args):
|
|
678
698
|
"""Returns a single row as a dictionary"""
|
|
679
699
|
crsr = self.execute( prmSql, *args )
|
|
680
700
|
dictRow = {} if crsr.EOF else crsr.fields
|
|
681
701
|
return dictRow
|
|
682
702
|
|
|
683
|
-
|
|
684
703
|
def fetchval(self, prmSql, *args):
|
|
685
704
|
"""Returns a single value"""
|
|
686
705
|
dictRow = self.fetchone( prmSql, *args )
|
|
687
706
|
listVals = list(dictRow.values())
|
|
688
707
|
return None if not listVals else listVals[0]
|
|
689
708
|
|
|
690
|
-
|
|
691
709
|
def insert(self, table, prmDict, update_on_duplicate=False):
|
|
692
710
|
if update_on_duplicate:
|
|
693
711
|
keystr = ','.join(prmDict.keys())
|
|
@@ -704,14 +722,12 @@ class dbObjConnection:
|
|
|
704
722
|
strSql = "INSERT INTO {table} ({keystr}) VALUES ({valstr})".format(table=table,keystr=keystr,valstr=valstr)
|
|
705
723
|
return self.execute(strSql, *args)
|
|
706
724
|
|
|
707
|
-
|
|
708
725
|
def updatedict(self, table, unique_column, unique_value, prmDict):
|
|
709
726
|
setstr = ",".join(["{k}=%s".format(k=k) for k in prmDict.keys()])
|
|
710
727
|
args = tuple(prmDict.values())
|
|
711
728
|
strSql = "UPDATE {table} SET {setstr} WHERE {unique_column} = {unique_value}".format(table=table,setstr=setstr,unique_column=unique_column,unique_value=unique_value)
|
|
712
729
|
return self.execute(strSql, *args)
|
|
713
730
|
|
|
714
|
-
|
|
715
731
|
def ping(self, reconnect=True):
|
|
716
732
|
if(self.dbType == "MYSQL"):
|
|
717
733
|
self.mySqlPing()
|
|
@@ -732,7 +748,6 @@ class dbObjConnection:
|
|
|
732
748
|
pass
|
|
733
749
|
self.progressPing()
|
|
734
750
|
|
|
735
|
-
|
|
736
751
|
def mySqlPing(self, reconnect=True):
|
|
737
752
|
"""
|
|
738
753
|
Check if the server is alive.
|
|
@@ -771,7 +786,6 @@ class dbObjConnection:
|
|
|
771
786
|
else:
|
|
772
787
|
raise Exception
|
|
773
788
|
|
|
774
|
-
|
|
775
789
|
def setMySqlExecuteFail(self, mySqlCursor, prmSql, e, *args):
|
|
776
790
|
self.msgObj.success = False
|
|
777
791
|
prmSql += '' if not args else ' ({0}) '.format( repr(args) )
|
|
@@ -801,7 +815,6 @@ class dbObjConnection:
|
|
|
801
815
|
finally:
|
|
802
816
|
return mySqlCursor
|
|
803
817
|
|
|
804
|
-
|
|
805
818
|
def mySqlExecute(self, prmSql, *args):
|
|
806
819
|
mySqlCursor = self.getCursor()
|
|
807
820
|
try:
|
|
@@ -838,7 +851,6 @@ class dbObjConnection:
|
|
|
838
851
|
mySqlCursor = self.setMySqlExecuteSuccess(mySqlCursor, prmSql, *args)
|
|
839
852
|
return mySqlCursor
|
|
840
853
|
|
|
841
|
-
|
|
842
854
|
def msSqlExecute(self, prmSql):
|
|
843
855
|
msSqlCursor = self.getCursor()
|
|
844
856
|
try:
|
|
@@ -857,7 +869,6 @@ class dbObjConnection:
|
|
|
857
869
|
msSqlCursor.next()
|
|
858
870
|
return msSqlCursor
|
|
859
871
|
|
|
860
|
-
|
|
861
872
|
def oracleExecute(self, prmSql):
|
|
862
873
|
oracleCursor = self.getCursor()
|
|
863
874
|
try:
|
|
@@ -879,7 +890,6 @@ class dbObjConnection:
|
|
|
879
890
|
oracleCursor.EOF = 1
|
|
880
891
|
return oracleCursor
|
|
881
892
|
|
|
882
|
-
|
|
883
893
|
def sqlite3Execute(self, prmSql):
|
|
884
894
|
sqliteCursor = self.getCursor()
|
|
885
895
|
try:
|
|
@@ -900,7 +910,6 @@ class dbObjConnection:
|
|
|
900
910
|
sqliteCursor.EOF = 1
|
|
901
911
|
return sqliteCursor
|
|
902
912
|
|
|
903
|
-
|
|
904
913
|
def progressExecute(self, prmSql):
|
|
905
914
|
progressCursor = self.getCursor()
|
|
906
915
|
try:
|
|
@@ -922,12 +931,55 @@ class dbObjConnection:
|
|
|
922
931
|
progressCursor.EOF = 1
|
|
923
932
|
return progressCursor
|
|
924
933
|
|
|
934
|
+
def apiExecute(self, prmSql):
|
|
935
|
+
apiCursor = self.getCursor()
|
|
936
|
+
apiCursor.success = False
|
|
937
|
+
try:
|
|
938
|
+
# convert sqls to url safe version
|
|
939
|
+
#sqls = requests.compat.quote_plus( prmSql )
|
|
940
|
+
#r = requests.post(self.apiBaseUrl + "/execute", data = {self.apiKeyName: self.apiKey, "sql": sqls})
|
|
941
|
+
sqls = prmSql
|
|
942
|
+
headers = {'Content-type':'application/json'}
|
|
943
|
+
payload = {self.apiKeyName: self.apiKey, "sql": sqls}
|
|
944
|
+
r = requests.post(self.apiBaseUrl + "/execute", data=json.dumps(payload), headers=headers)
|
|
945
|
+
#print(r.request.body)
|
|
946
|
+
#print(r.request.headers)
|
|
947
|
+
if(r.status_code == requests.codes.ok):
|
|
948
|
+
retVal = r.json()
|
|
949
|
+
#print(retVal)
|
|
950
|
+
if(retVal["error"] == 0):
|
|
951
|
+
apiCursor.lstRecords = retVal["data"]
|
|
952
|
+
apiCursor.numRows = len(apiCursor.lstRecords)
|
|
953
|
+
if(apiCursor.numRows > 0):
|
|
954
|
+
apiCursor.numFields = len(apiCursor.lstRecords[0].keys())
|
|
955
|
+
apiCursor.EOF = 0
|
|
956
|
+
self.lastInsId = retVal["message"]
|
|
957
|
+
apiCursor.next()
|
|
958
|
+
else:
|
|
959
|
+
apiCursor.numFields = 0
|
|
960
|
+
apiCursor.EOF = 1
|
|
961
|
+
apiCursor.success = True
|
|
962
|
+
self.msgObj.message = "SQL Executed: "+prmSql
|
|
963
|
+
self.msgObj.success = True
|
|
964
|
+
else:
|
|
965
|
+
self.msgObj.message = "SQL Failed: "+str(retVal["message"])
|
|
966
|
+
self.msgObj.success = False
|
|
967
|
+
else:
|
|
968
|
+
self.msgObj.message = "SQL Failed: "+str(r.status_code)
|
|
969
|
+
self.msgObj.success = False
|
|
970
|
+
except Exception as e:
|
|
971
|
+
self.msgObj.message = "SQL Failed: "+prmSql+" - "+str(e)
|
|
972
|
+
self.msgObj.success = False
|
|
973
|
+
apiCursor.numFields = 0
|
|
974
|
+
apiCursor.numRows = 0
|
|
975
|
+
apiCursor.EOF = 1
|
|
976
|
+
apiCursor.success = False
|
|
977
|
+
return apiCursor
|
|
925
978
|
|
|
926
979
|
def commit(self):
|
|
927
980
|
if(self.dbType == "MYSQL"):
|
|
928
981
|
self.connHandle.commit()
|
|
929
982
|
|
|
930
|
-
|
|
931
983
|
if __name__ == '__main__':
|
|
932
984
|
import time, pprint
|
|
933
985
|
pp = pprint.PrettyPrinter(indent=4, width=80).pprint
|
|
@@ -940,7 +992,6 @@ if __name__ == '__main__':
|
|
|
940
992
|
else:
|
|
941
993
|
return input(prompt,*args,**kwargs)
|
|
942
994
|
|
|
943
|
-
|
|
944
995
|
def dbtest():
|
|
945
996
|
dbhost = getInput( "MySQL Hostname: " )
|
|
946
997
|
dbname = getInput( "MySQL Database Name: ")
|
|
@@ -952,7 +1003,6 @@ if __name__ == '__main__':
|
|
|
952
1003
|
print( "message: {v}".format(v=result.message) )
|
|
953
1004
|
return odb if result.success else None
|
|
954
1005
|
|
|
955
|
-
|
|
956
1006
|
def sqltest(dbConn=None,sqls=''):
|
|
957
1007
|
sqls = sqls or getInput( "\nEnter SQL Statement: ")
|
|
958
1008
|
t0 = time.time()
|
|
@@ -971,7 +1021,6 @@ if __name__ == '__main__':
|
|
|
971
1021
|
print('\n')
|
|
972
1022
|
return sqls, rset
|
|
973
1023
|
|
|
974
|
-
|
|
975
1024
|
def run_test():
|
|
976
1025
|
odb = None
|
|
977
1026
|
print("<enter> for yes or 'n' for no\n")
|
|
@@ -1022,7 +1071,5 @@ if __name__ == '__main__':
|
|
|
1022
1071
|
odb.autoreconnect = True
|
|
1023
1072
|
return odb
|
|
1024
1073
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
1074
|
# odb will be the interactively instantiated dbObj connection
|
|
1028
1075
|
odb = run_test()
|
|
File without changes
|