File: pysqliteBrowse.py

package info (click to toggle)
pythoncard 0.8.2-2
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 8,452 kB
  • sloc: python: 56,787; makefile: 56; sh: 22
file content (105 lines) | stat: -rw-r--r-- 4,277 bytes parent folder | download | duplicates (3)
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 "--------------------------------------------------"