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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: dbobj3
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: High-level MySQL/MSSQL/Oracle access module
5
5
  Requires-Python: >=3.6
6
6
  Requires-Dist: pymysql
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dbobj3"
7
- version = "0.3.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.3.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.3.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
- pass
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
- pass
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
- pass
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
- pass
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
- pass
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
- pass
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 PROGRESS
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="", prmPort=3306,
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.host, self.db, self.user, self.passwd, self.port = prmHost, prmDb, prmUser, prmPass, prmPort
341
- if( self.dbType and self.host and self.db and self.user and self.passwd and self.port ):
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
- prmHost = prmHost or self.host
381
- prmDb = prmDb or self.db
382
- prmUser = prmUser or self.user
383
- prmPass = prmPass or self.passwd
384
- prmPort = prmPort or self.port
385
- self.host, self.db, self.user, self.passwd, self.port = prmHost, prmDb, prmUser, prmPass, prmPort
386
- if(self.dbType == "MYSQL"):
387
- return self.mySqlConnect(prmHost, prmDb, prmUser, prmPass, prmPort)
388
- elif(self.dbType == "MSSQL"):
389
- return self.msSqlConnect(prmHost, prmDb, prmUser, prmPass)
390
- elif(self.dbType == "ORACLE"):
391
- return self.oracleConnect(prmUser, prmPass, prmDb)
392
- elif(self.dbType == "SQLITE" or self.dbType == "SQLITE3"):
393
- return self.sqlite3Connect(prmDb)
394
- elif(self.dbType == "PROGRESS"):
395
- return self.progressConnect(prmHost, prmDb, prmUser, prmPass, prmPort)
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