dbobj3 0.1.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.
dbobj3-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.5
2
+ Name: dbobj3
3
+ Version: 0.1.0
4
+ Summary: High-level MySQL/MSSQL/Oracle access module
5
+ Requires-Python: >=3.6
6
+ Requires-Dist: pymysql
7
+ Description-Content-Type: text/markdown
8
+
9
+ # dbobj3
10
+
11
+ High-level database access module for MySQL, MS SQL Server, and Oracle.
12
+ Works identically across all supported databases.
dbobj3-0.1.0/README.md ADDED
@@ -0,0 +1,4 @@
1
+ # dbobj3
2
+
3
+ High-level database access module for MySQL, MS SQL Server, and Oracle.
4
+ Works identically across all supported databases.
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "dbobj3"
7
+ version = "0.1.0"
8
+ description = "High-level MySQL/MSSQL/Oracle access module"
9
+ readme = "README.md"
10
+ requires-python = ">=3.6"
11
+ dependencies = [
12
+ "PyMySQL",
13
+ ]
14
+
15
+ [tool.hatch.build.targets.wheel]
16
+ packages = ["src/dbobj3.py"]
17
+
18
+ [tool.bumpversion]
19
+ current_version = "0.1.0"
20
+ commit = true
21
+ tag = true
22
+ parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)"
23
+ serialize = ["{major}.{minor}"]
24
+
25
+ [[tool.bumpversion.files]]
26
+ filename = "pyproject.toml"
27
+ search = 'version = "{current_version}"'
28
+ replace = 'version = "{new_version}"'
29
+
30
+ [[tool.bumpversion.files]]
31
+ filename = "src/dbobj3.py"
32
+ search = '__version__ = "{current_version}"'
33
+ replace = '__version__ = "{new_version}"'
@@ -0,0 +1,458 @@
1
+ #!/usr/local/bin/python3.6
2
+
3
+ """
4
+ High-Level Access to MySQL, MS SQL Server and Oracle Module
5
+ This module functions the same across all databases and works very similarly to ADO.
6
+
7
+ This module is the latest version of dbObj which has been in use for some time.
8
+ This module does not change the case of fields that are returned in record sets.
9
+
10
+ Example:
11
+ myuser = input("MySQL Username: ")
12
+ mypassword = getpass.getpass()
13
+ connDb1a = dbObjConnection()
14
+ result = connDb1a.connect("db1a", "internet", myuser, mypassword)
15
+ rsServices = connDb1a.execute("select * from services")
16
+ while(not rsServices.EOF):
17
+ print(rsServices.fields["description"]
18
+ strSql = "select count(*) as ct from userservices where serviceid = '"+str(rsServices.fields["serviceid"])+"'"
19
+ rsCount = connDb1a.execute(strSql)
20
+ print(rsCount.fields["ct"]
21
+ rsServices.next()
22
+
23
+ """
24
+
25
+ __version__ = "0.1.0"
26
+
27
+ import MySQLdb
28
+ import MySQLdb.cursors
29
+ import pymssql
30
+ import sqlite3
31
+ import getpass
32
+ try:
33
+ import cx_Oracle
34
+ except ImportError:
35
+ pass
36
+
37
+ class dbConnMessage:
38
+ """
39
+ The dbConnMessage is an object that is returned in response to a dbObjConnection. It has two
40
+ properties:
41
+ success - True or False
42
+ message - Generally, reason for failure
43
+ """
44
+ def __init__(self):
45
+ self.success = False
46
+ self.message = ""
47
+
48
+ class dbObjCursor:
49
+ """
50
+ Database cursor object controls the cursor connected to a database. Multiple cursors
51
+ can exist for a single Database connection object
52
+ """
53
+ def __init__(self, prmConnection=None, prmDBType="MYSQL"):
54
+ self.EOF = 1
55
+ self.connection = prmConnection
56
+ self.cursor = None
57
+ self.numFields = 0
58
+ self.numRows = 0
59
+ self.lstRecords = [] # Used by Oracle and Sqlite3
60
+ self.recordPointer = 0
61
+ self.success = True
62
+ self.dbType = prmDBType.upper()
63
+ self.create(self.dbType)
64
+
65
+ def __del__(self):
66
+ if(self.dbType == "MYSQL"):
67
+ self.cursor.close()
68
+
69
+ def create(self, prmDBType="MYSQL"):
70
+ if(prmDBType=="MYSQL"):
71
+ self.createMySql()
72
+ elif(prmDBType=="MSSQL"):
73
+ self.createMsSql()
74
+ elif(prmDBType=="ORACLE"):
75
+ self.createOracle()
76
+ elif(prmDBType=="SQLITE" or prmDBType=="SQLITE3"):
77
+ self.createSqlite3()
78
+
79
+ def createMySql(self):
80
+ self.cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
81
+
82
+ def createMsSql(self):
83
+ self.cursor = self.connection.cursor(as_dict=True)
84
+
85
+ def createOracle(self):
86
+ self.cursor = self.connection.cursor()
87
+
88
+ def createSqlite3(self):
89
+ self.cursor = self.connection.cursor()
90
+
91
+ def moveNext(self):
92
+ """Same as next"""
93
+ self.next()
94
+
95
+ def next(self):
96
+ """Move to the next record in the record set and loads the data into the fields property. Sets EOF at end of records."""
97
+ if(self.dbType == "MYSQL"):
98
+ self.mySqlNext()
99
+ elif(self.dbType == "MSSQL"):
100
+ self.msSqlNext()
101
+ elif(self.dbType == "ORACLE"):
102
+ self.oracleNext()
103
+ elif(self.dbType == "SQLITE" or self.dbType == "SQLITE3"):
104
+ self.sqlite3Next()
105
+
106
+ def mySqlNext(self):
107
+ resultSet = self.cursor.fetchone()
108
+ if(resultSet != None):
109
+ self.fieldByName = resultSet
110
+ self.fields = self.fieldByName
111
+ self.EOF = 0
112
+ else:
113
+ self.fieldByName = {}
114
+ self.fields = self.fieldByName
115
+ self.EOF = 1
116
+
117
+ def msSqlNext(self):
118
+ try:
119
+ resultSet = self.cursor.fetchone()
120
+ except Exception as e:
121
+ print(e)
122
+ self.EOF = 1
123
+ return
124
+ if(resultSet != None):
125
+ self.fields = resultSet
126
+ self.EOF = 0
127
+ else:
128
+ self.EOF = 1
129
+
130
+ def oracleNext(self):
131
+ if(self.recordPointer <= self.numRows):
132
+ self.fieldByName = {}
133
+ self.fieldNames = []
134
+ fieldNo = 0
135
+ for cursorFieldname in self.cursor.description:
136
+ self.fieldByName[cursorFieldname[0]] = self.lstRecords[(self.recordPointer-1)][fieldNo]
137
+ self.fieldNames.append(cursorFieldname[0])
138
+ fieldNo = fieldNo + 1
139
+ self.fields = self.fieldByName
140
+ self.recordPointer += 1
141
+ self.EOF = 0
142
+ else:
143
+ self.EOF = 1
144
+
145
+ def sqlite3Next(self):
146
+ if(self.recordPointer <= self.numRows):
147
+ self.fieldByName = {}
148
+ self.fieldNames = []
149
+ fieldNo = 0
150
+ for cursorFieldname in self.cursor.description:
151
+ self.fieldByName[cursorFieldname[0]] = self.lstRecords[(self.recordPointer-1)][fieldNo]
152
+ self.fieldNames.append(cursorFieldname[0])
153
+ fieldNo = fieldNo + 1
154
+ self.fields = self.fieldByName
155
+ self.recordPointer += 1
156
+ self.EOF = 0
157
+ else:
158
+ self.EOF = 1
159
+
160
+ def first(self):
161
+ """Move to the next record in the record set and loads the data into the fields property. Sets EOF at end of records."""
162
+ if(self.dbType == "MYSQL"):
163
+ self.mySqlFirst()
164
+
165
+ def mySqlFirst(self):
166
+ resultSet = self.cursor.scroll(0,'absolute')
167
+ self.mySqlNext()
168
+
169
+ def oracleExecute(self, prmSql):
170
+ """
171
+ Oracle had to be handled differently due to cursor.rowcount failing. This method is called
172
+ transparently by dbObjConnection.execute and fetches all records at once where the other
173
+ database types do not.
174
+ """
175
+ self.cursor.execute(prmSql)
176
+ self.lstRecords = self.cursor.fetchall()
177
+ self.numRows = len(self.lstRecords)
178
+ self.numFields = len(self.cursor.description)
179
+ if(self.numRows > 0):
180
+ self.recordPointer = 1
181
+
182
+ def sqlite3Execute(self, prmSql):
183
+ """
184
+ Sqlite3 method is called transparently by dbObjConnection.execute and fetches all records at once where the other
185
+ database types do not.
186
+ """
187
+ self.cursor.execute(prmSql)
188
+ self.lstRecords = self.cursor.fetchall()
189
+ self.numRows = len(self.lstRecords)
190
+ self.numFields = len(self.cursor.description)
191
+ if(self.numRows > 0):
192
+ self.recordPointer = 1
193
+
194
+ class dbObjConnection:
195
+ """
196
+ dbObjConnection is the database connection object. It is responsible for connecting to
197
+ the database. This object supports access to MySQL, Microsoft SQL Server and Oracle.
198
+ """
199
+ def __init__(self, prmDBType="MYSQL"):
200
+ """prmDBType can be: MYSQL, MSSQL, or ORACLE"""
201
+ self.EOF = 1
202
+ self.connHandle = 0
203
+ self.dbType = prmDBType.upper()
204
+ self.msgObj = dbConnMessage()
205
+ self.lastInsId = 0
206
+
207
+ def __del__(self):
208
+ """The default destructor will close the connection"""
209
+ if(self.dbType == "MYSQL"):
210
+ self.connHandle.commit()
211
+ self.connHandle.close()
212
+
213
+ def connect(self, prmHost="", prmDb="", prmUser="", prmPass=""):
214
+ """
215
+ MySQL:
216
+ result = connMySQL.connect("db1a", "internet", myuser, mypassword)
217
+ MS SQL:
218
+ result = connMSSQL.connect("flexibill-mssql", "FLEXIBILL", msuser, mspassword)
219
+ Oracle:
220
+ result = connOracl.connect("", "MDDB", orauser, orapassword)
221
+
222
+ returns: dbConnMessage
223
+ """
224
+ if(self.dbType == "MYSQL"):
225
+ return self.mySqlConnect(prmHost, prmDb, prmUser, prmPass)
226
+ elif(self.dbType == "MSSQL"):
227
+ return self.msSqlConnect(prmHost, prmDb, prmUser, prmPass)
228
+ elif(self.dbType == "ORACLE"):
229
+ return self.oracleConnect(prmUser, prmPass, prmDb)
230
+ elif(self.dbType == "SQLITE" or self.dbType == "SQLITE3"):
231
+ return self.sqlite3Connect(prmDb)
232
+
233
+ def mySqlConnect(self, prmHost, prmDb, prmUser, prmPass):
234
+ try:
235
+ self.connHandle = MySQLdb.connect(host=prmHost,db=prmDb,user=prmUser,passwd=prmPass)
236
+ if(self.connHandle):
237
+ self.msgObj.message = "Connected to MySqlDatabase okay."
238
+ self.msgObj.success = True
239
+ else:
240
+ self.msgObj.message = "Connection Failed."
241
+ self.msgObj.success = False
242
+ except Exception as e:
243
+ self.msgObj.message = "Connection Failed: "+str(e)
244
+ self.msgObj.success = False
245
+ return self.msgObj
246
+
247
+ def msSqlConnect(self, prmHost, prmDb, prmUser, prmPass):
248
+ try:
249
+ self.connHandle = pymssql.connect(prmHost, prmUser, prmPass, prmDb)
250
+ self.connHandle.autocommit(True)
251
+ if(self.connHandle):
252
+ self.msgObj.message = "Connected to MS SQL Database okay."
253
+ self.msgObj.success = True
254
+ else:
255
+ self.msgObj.message = "Connection Failed."
256
+ self.msgObj.success = False
257
+ except Exception as e:
258
+ self.msgObj.message = "Connection Failed: "+str(e)
259
+ self.msgObj.success = False
260
+ return self.msgObj
261
+
262
+ def oracleConnect(self, prmUser, prmPass, prmTns):
263
+ try:
264
+ self.connHandle = cx_Oracle.connect(prmUser, prmPass, prmTns)
265
+ if(self.connHandle):
266
+ self.msgObj.message = "Connected to Oracle Database okay."
267
+ self.msgObj.success = True
268
+ else:
269
+ self.msgObj.message = "Connection Failed."
270
+ self.msgObj.success = False
271
+ except Exception as e:
272
+ self.msgObj.message = "Connection Failed: "+str(e)
273
+ self.msgObj.success = False
274
+ return self.msgObj
275
+
276
+ def sqlite3Connect(self, prmDb):
277
+ try:
278
+ self.connHandle = sqlite3.connect(prmDb)
279
+ self.connHandle.row_factory = sqlite3.Row
280
+ if(self.connHandle):
281
+ self.msgObj.message = "Connected to Sqlite3 Database okay."
282
+ self.msgObj.success = True
283
+ else:
284
+ self.msgObj.message = "Connection Failed."
285
+ self.msgObj.success = False
286
+ except Exception as e:
287
+ self.msgObj.message = "Connection Failed: "+str(e)
288
+ self.msgObj.success = False
289
+ return self.msgObj
290
+
291
+ def disconnect(self):
292
+ """Disconnect the connection handle to the database"""
293
+ if(self.dbType == "MYSQL"):
294
+ self.mySqlDisconnect()
295
+ elif(self.dbType == "MSSQL"):
296
+ self.msSqlDisconnect()
297
+ elif(self.dbType == "ORACLE"):
298
+ self.oracleDisconnect()
299
+ elif(self.dbType == "SQLITE" or self.dbType == "SQLITE3"):
300
+ self.sqlite3Disconnect()
301
+
302
+ def mySqlDisconnect(self):
303
+ self.connHandle.close()
304
+
305
+ def msSqlDisconnect(self):
306
+ self.connHandle.close()
307
+
308
+ def oracleDisconnect(self):
309
+ self.connHandle.close()
310
+
311
+ def sqlite3Disconnect(self):
312
+ self.connHandle.close()
313
+
314
+ def execute(self, prmSql):
315
+ """Execute the SQL and return a record set if applicable"""
316
+ if(self.dbType == "MYSQL"):
317
+ return self.mySqlExecute(prmSql)
318
+ if(self.dbType == "MSSQL"):
319
+ return self.msSqlExecute(prmSql)
320
+ if(self.dbType == "ORACLE"):
321
+ return self.oracleExecute(prmSql)
322
+
323
+ def mySqlExecute(self, prmSql):
324
+ mySqlCursor = dbObjCursor(self.connHandle)
325
+ try:
326
+ mySqlCursor.cursor.execute(prmSql)
327
+ self.msgObj.message = "SQL Executed: "+prmSql
328
+ self.msgObj.success = True
329
+ mySqlCursor.numRows = mySqlCursor.cursor.rowcount
330
+ self.lastInsId = self.connHandle.insert_id()
331
+ except Exception as e:
332
+ self.msgObj.message = "SQL Failed: "+prmSql+" - "+str(e)
333
+ self.msgObj.success = False
334
+ mySqlCursor.numFields = 0
335
+ mySqlCursor.numRows = 0
336
+ mySqlCursor.EOF = 1
337
+ mySqlCursor.success = False
338
+ return mySqlCursor
339
+ try:
340
+ mySqlCursor.numFields = len(mySqlCursor.cursor.description)
341
+ except:
342
+ mySqlCursor.numFields = 0
343
+ if(mySqlCursor.numRows):
344
+ mySqlCursor.next()
345
+ else:
346
+ mySqlCursor.EOF = 1
347
+ return mySqlCursor
348
+
349
+ def msSqlExecute(self, prmSql):
350
+ msSqlCursor = dbObjCursor(self.connHandle, "MSSQL")
351
+ try:
352
+ msSqlCursor.cursor.execute(prmSql)
353
+ self.msgObj.message = "SQL Executed: "+prmSql
354
+ self.msgObj.success = True
355
+ except Exception as e:
356
+ self.msgObj.message = "SQL Failed: "+prmSql+" - "+str(e)
357
+ self.msgObj.success = False
358
+ msSqlCursor.numFields = 0
359
+ msSqlCursor.numRows = 0
360
+ msSqlCursor.EOF = 1
361
+ msSqlCursor.success = False
362
+ return mySqlCursor
363
+ msSqlCursor.next()
364
+ return msSqlCursor
365
+
366
+ def oracleExecute(self, prmSql):
367
+ oracleCursor = dbObjCursor(self.connHandle, "ORACLE")
368
+ try:
369
+ oracleCursor.oracleExecute(prmSql)
370
+ self.msgObj.message = "SQL Executed: "+prmSql
371
+ self.msgObj.success = True
372
+ except Exception as e:
373
+ self.msgObj.message = "SQL Failed: "+prmSql+" - "+str(e)
374
+ self.msgObj.success = False
375
+ print(str(e))
376
+ oracleCursor.numFields = 0
377
+ oracleCursor.numRows = 0
378
+ oracleCursor.EOF = 1
379
+ oracleCursor.success = False
380
+ return mySqlCursor
381
+ if(oracleCursor.numRows):
382
+ oracleCursor.next()
383
+ else:
384
+ oracleCursor.EOF = 1
385
+ return oracleCursor
386
+
387
+ def commit(self):
388
+ if(self.dbType == "MYSQL"):
389
+ self.connHandle.commit()
390
+
391
+ if __name__== '__main__' :
392
+ # MySQL Testing - two cursors - nested
393
+ print("********************** MySQL Test **********************")
394
+ myuser = input("MySQL Username: ")
395
+ mypassword = getpass.getpass()
396
+ conn = dbObjConnection()
397
+ result = conn.connect("127.0.0.1", "internet", myuser, mypassword)
398
+ print(result.message)
399
+ if(result.success):
400
+ try:
401
+ rsServices = conn.execute("select * from services")
402
+ while(not rsServices.EOF):
403
+ print(rsServices.fields["description"])
404
+ strSql = "select count(*) as ct from userservices where serviceid = '"+str(rsServices.fields["serviceid"])+"'"
405
+ rsCount = conn.execute(strSql)
406
+ #print(rsCount.fields["ct"])
407
+ rsServices.next()
408
+ rsServices.first()
409
+ print("-----------------------------")
410
+ while(not rsServices.EOF):
411
+ print(rsServices.fields["description"])
412
+ strSql = "select count(*) as ct from userservices where serviceid = '"+str(rsServices.fields["serviceid"])+"'"
413
+ rsCount = conn.execute(strSql)
414
+ #print(rsCount.fields["ct"])
415
+ rsServices.next()
416
+ except Exception as e:
417
+ print(e)
418
+ # MS SQL Testing
419
+ try:
420
+ print("********************** MS SQL Server Test **********************")
421
+ msuser = input("MS SQL Server Username: ")
422
+ mspassword = getpass.getpass()
423
+ conn2 = dbObjConnection("MSSQL")
424
+ result = conn2.connect("flexibill-mssql", "FLEXIBILL", msuser, mspassword)
425
+ print(result.message)
426
+ print(result.success)
427
+ rsExgTab = conn2.execute("SELECT * FROM EXGTAB")
428
+ while(not rsExgTab.EOF):
429
+ print(rsExgTab.fields["EXCHANGE"])
430
+ rsExgTab.moveNext()
431
+ #rsExgTab.first()
432
+ #print"-----------------------------------")
433
+ #while(not rsExgTab.EOF):
434
+ # print(rsExgTab.fields["EXCHANGE"])
435
+ # rsExgTab.moveNext()
436
+ #rsNextCustPsocAcct = conn2.execute("EXEC GETNEXTCUSTPSOCACCT")
437
+ #print(rsNextCustPsocAcct.fields)
438
+ except Exception as e:
439
+ print(e)
440
+ # Oracle Testing
441
+ try:
442
+ print("********************** Oracle Test **********************")
443
+ orauser = input("Oracle Server Username: ")
444
+ orapassword = getpass.getpass()
445
+ conn3 = dbObjConnection("ORACLE")
446
+ result = conn3.connect("", "MDDB", orauser, orapassword)
447
+ print(result.message)
448
+ print(result.success)
449
+ rsChannel = conn3.execute("select * from channel")
450
+ x=1
451
+ while(not rsChannel.EOF):
452
+ print(str(x)+" - "+ rsChannel.fields["CHANNEL_NAME"])
453
+ x+= 1
454
+ #print(rsChannel.fields)
455
+ rsChannel.moveNext()
456
+ print("Total records: "+str(rsChannel.numRows))
457
+ except Exception as e:
458
+ print(e)