1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#!/usr/bin/python
"""
Module Name: gadflyBrowse
Description: Plug in for PythonCard application dbBrowse to provide Gadfly specific functionality
Constant/configuration values are currently maintained in the source code. If we are to optimise this application they should be split into seperate configuration files (as per PythonCard/Webware style guidelines)
The structure of this module should be replicated for different RDBMS so that they can be interchanged by dbBrowse - hopefully.
"""
__version__="$Revision $"[11:-2]
__date__="$Date $"
__author__="Andy Todd <andy47@halfcooked.com>"
# KEA 2003-01-19
# see http://www.hwaci.com/sw/sqlite/faq.html
import sqlite
import os
class browse:
# Connection should be a dictionary with at least two keys,
# 'databasename' and 'directory'
# This is wildly different to other database modules
def __init__(self, connection):
"Setup the database connection"
self._system_tables=[]
if not connection['databasename']:
raise ValueError
filename = os.path.join(connection['directory'], connection['databasename'])
# not sure about the mode to use, I assume we just want read-only
self._db = sqlite.connect(db=filename, mode=077)
self._cursor=self._db.cursor()
# This one is used in getRow
self._tableName=''
def getTables(self):
"Return a list of all of the non-system tables in <database>"
##stmt = "SELECT table_name FROM __table_names__"
stmt = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;"
self._cursor.execute(stmt)
# I'm using a list comprehension here instead of a for loop,
# either will do but I think this is more concise (unlike this comment)
return [ x[0] for x in self._cursor.fetchall() if x[0] not in self._system_tables ]
def getColumns(self, tableName):
"Get the definition of the columns in tableName"
stmt = "select * from " + tableName
self._cursor.execute(stmt)
row = self._cursor.fetchone()
columnDefs = []
for column in row.keys():
columnName = column
dataType, nullable, key, default = "varchar", "", "", ""
# Dodgy default, but if works for me
precision = 255
columnDefs.append((columnName, dataType, precision, nullable, key, default))
return columnDefs
def getQueryString(self, tableName):
"Return a SQL statement which queries all of the columns in tableName"
tableStructure=self.getColumns(tableName)
# Construct and return the string
stmt='SELECT '
for columnList in tableStructure:
stmt+=columnList[0]+', '
stmt=stmt[:-2]+' FROM '+tableName
return stmt
def getRow(self, tableName):
"Get a row from tableName"
# When we upgrade to 2.2 this will be a great candidate for a
# generator/iterator. In the meantime we use self._tableName to keep
# track of what we are doing
if tableName!=self._tableName:
self._tableName=tableName
self._cursor.execute(self.getQueryString(tableName))
result = self._cursor.fetchone()
return result
def getRows(self, tableName):
"Get all of the rows from tableName"
if tableName!=self._tableName:
self._tableName=tableName
self._cursor.execute(self.getQueryString(tableName))
result=self._cursor.fetchall()
return result
if __name__ == '__main__':
# We are in an interactive session so run our test routines
# Connect to the database
##connection={ 'databasename':'andy'
## ,'directory':'E:\Gadfly'}
connection={'databasename':'calflora.db', 'directory':'.'}
dbHolder = browse(connection)
# Return all of our table names into user_tables
user_tables = dbHolder.getTables()
# Print out the structure of each table and its first row
print "--------------------------------------------------"
for table in user_tables:
print "table:", table
print dbHolder.getQueryString(table)
print dbHolder.getRow(table)
print "--------------------------------------------------"
|