188 lines
5.6 KiB
Python
188 lines
5.6 KiB
Python
|
#
|
||
|
# 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 os
|
||
|
import sys
|
||
|
|
||
|
import pythoncom
|
||
|
import win32api
|
||
|
from win32com.client import Dispatch, constants, gencache
|
||
|
|
||
|
|
||
|
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):
|
||
|
from . 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()
|