testAccess.py
5.54 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#
# This assumes that you have MSAccess and DAO installed.
# You need to run makepy.py over "msaccess.tlb" and
# "dao3032.dll", and ensure the generated files are on the
# path.
# You can run this with no args, and a test database will be generated.
# You can optionally pass a dbname on the command line, in which case it will be dumped.
import pythoncom
from win32com.client import gencache, constants, Dispatch
import win32api
import os, sys
def CreateTestAccessDatabase(dbname = None):
# Creates a test access database - returns the filename.
if dbname is None:
dbname = os.path.join( win32api.GetTempPath(), "COMTestSuiteTempDatabase.mdb" )
access = Dispatch("Access.Application")
dbEngine = access.DBEngine
workspace = dbEngine.Workspaces(0)
try:
os.unlink(dbname)
except os.error:
print "WARNING - Unable to delete old test database - expect a COM exception RSN!"
newdb = workspace.CreateDatabase( dbname, constants.dbLangGeneral, constants.dbEncrypt )
# Create one test table.
table = newdb.CreateTableDef("Test Table 1")
table.Fields.Append( table.CreateField("First Name", constants.dbText ) )
table.Fields.Append( table.CreateField("Last Name", constants.dbText ) )
index = table.CreateIndex("UniqueIndex")
index.Fields.Append( index.CreateField("First Name") )
index.Fields.Append( index.CreateField("Last Name") )
index.Unique = -1
table.Indexes.Append(index)
newdb.TableDefs.Append( table )
# Create a second test table.
table = newdb.CreateTableDef("Test Table 2")
table.Fields.Append( table.CreateField("First Name", constants.dbText ) )
table.Fields.Append( table.CreateField("Last Name", constants.dbText ) )
newdb.TableDefs.Append( table )
# Create a relationship between them
relation = newdb.CreateRelation("TestRelationship")
relation.Table = "Test Table 1"
relation.ForeignTable = "Test Table 2"
field = relation.CreateField("First Name")
field.ForeignName = "First Name"
relation.Fields.Append( field )
field = relation.CreateField("Last Name")
field.ForeignName = "Last Name"
relation.Fields.Append( field )
relation.Attributes = constants.dbRelationDeleteCascade + constants.dbRelationUpdateCascade
newdb.Relations.Append(relation)
# Finally we can add some data to the table.
tab1 = newdb.OpenRecordset("Test Table 1")
tab1.AddNew()
tab1.Fields("First Name").Value = "Mark"
tab1.Fields("Last Name").Value = "Hammond"
tab1.Update()
tab1.MoveFirst()
# We do a simple bookmark test which tests our optimized VT_SAFEARRAY|VT_UI1 support.
# The bookmark will be a buffer object - remember it for later.
bk = tab1.Bookmark
# Add a second record.
tab1.AddNew()
tab1.Fields("First Name").Value = "Second"
tab1.Fields("Last Name").Value = "Person"
tab1.Update()
# Reset the bookmark to the one we saved.
# But first check the test is actually doing something!
tab1.MoveLast()
if tab1.Fields("First Name").Value != "Second":
raise RuntimeError("Unexpected record is last - makes bookmark test pointless!")
tab1.Bookmark = bk
if tab1.Bookmark != bk:
raise RuntimeError("The bookmark data is not the same")
if tab1.Fields("First Name").Value != "Mark":
raise RuntimeError("The bookmark did not reset the record pointer correctly")
return dbname
def DoDumpAccessInfo(dbname):
import daodump
a = forms = None
try:
sys.stderr.write("Creating Access Application...\n")
a=Dispatch("Access.Application")
print "Opening database %s" % dbname
a.OpenCurrentDatabase(dbname)
db = a.CurrentDb()
daodump.DumpDB(db,1)
forms = a.Forms
print "There are %d forms open." % (len(forms))
# Uncommenting these lines means Access remains open.
# for form in forms:
# print " %s" % form.Name
reports = a.Reports
print "There are %d reports open" % (len(reports))
finally:
if not a is None:
sys.stderr.write("Closing database\n")
try:
a.CloseCurrentDatabase()
except pythoncom.com_error:
pass
# Generate all the support we can.
def GenerateSupport():
# dao
gencache.EnsureModule("{00025E01-0000-0000-C000-000000000046}", 0, 4, 0)
# Access
# gencache.EnsureModule("{4AFFC9A0-5F99-101B-AF4E-00AA003F0F07}", 0, 8, 0)
gencache.EnsureDispatch("Access.Application")
def DumpAccessInfo(dbname):
amod = gencache.GetModuleForProgID("Access.Application")
dmod = gencache.GetModuleForProgID("DAO.DBEngine.35")
if amod is None and dmod is None:
DoDumpAccessInfo(dbname)
# Now generate all the support we can.
GenerateSupport()
else:
sys.stderr.write("testAccess not doing dynamic test, as generated code already exists\n")
# Now a generated version.
DoDumpAccessInfo(dbname)
def test(dbname = None):
if dbname is None:
# We need makepy support to create a database (just for the constants!)
try:
GenerateSupport()
except pythoncom.com_error:
print "*** Can not import the MSAccess type libraries - tests skipped"
return
dbname = CreateTestAccessDatabase()
print "A test database at '%s' was created" % dbname
DumpAccessInfo(dbname)
if __name__=='__main__':
import sys
from util import CheckClean
dbname = None
if len(sys.argv)>1:
dbname = sys.argv[1]
test(dbname)
CheckClean()