testAccess.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #
  2. # This assumes that you have MSAccess and DAO installed.
  3. # You need to run makepy.py over "msaccess.tlb" and
  4. # "dao3032.dll", and ensure the generated files are on the
  5. # path.
  6. # You can run this with no args, and a test database will be generated.
  7. # You can optionally pass a dbname on the command line, in which case it will be dumped.
  8. import pythoncom
  9. from win32com.client import gencache, constants, Dispatch
  10. import win32api
  11. import os, sys
  12. def CreateTestAccessDatabase(dbname = None):
  13. # Creates a test access database - returns the filename.
  14. if dbname is None:
  15. dbname = os.path.join( win32api.GetTempPath(), "COMTestSuiteTempDatabase.mdb" )
  16. access = Dispatch("Access.Application")
  17. dbEngine = access.DBEngine
  18. workspace = dbEngine.Workspaces(0)
  19. try:
  20. os.unlink(dbname)
  21. except os.error:
  22. print("WARNING - Unable to delete old test database - expect a COM exception RSN!")
  23. newdb = workspace.CreateDatabase( dbname, constants.dbLangGeneral, constants.dbEncrypt )
  24. # Create one test table.
  25. table = newdb.CreateTableDef("Test Table 1")
  26. table.Fields.Append( table.CreateField("First Name", constants.dbText ) )
  27. table.Fields.Append( table.CreateField("Last Name", constants.dbText ) )
  28. index = table.CreateIndex("UniqueIndex")
  29. index.Fields.Append( index.CreateField("First Name") )
  30. index.Fields.Append( index.CreateField("Last Name") )
  31. index.Unique = -1
  32. table.Indexes.Append(index)
  33. newdb.TableDefs.Append( table )
  34. # Create a second test table.
  35. table = newdb.CreateTableDef("Test Table 2")
  36. table.Fields.Append( table.CreateField("First Name", constants.dbText ) )
  37. table.Fields.Append( table.CreateField("Last Name", constants.dbText ) )
  38. newdb.TableDefs.Append( table )
  39. # Create a relationship between them
  40. relation = newdb.CreateRelation("TestRelationship")
  41. relation.Table = "Test Table 1"
  42. relation.ForeignTable = "Test Table 2"
  43. field = relation.CreateField("First Name")
  44. field.ForeignName = "First Name"
  45. relation.Fields.Append( field )
  46. field = relation.CreateField("Last Name")
  47. field.ForeignName = "Last Name"
  48. relation.Fields.Append( field )
  49. relation.Attributes = constants.dbRelationDeleteCascade + constants.dbRelationUpdateCascade
  50. newdb.Relations.Append(relation)
  51. # Finally we can add some data to the table.
  52. tab1 = newdb.OpenRecordset("Test Table 1")
  53. tab1.AddNew()
  54. tab1.Fields("First Name").Value = "Mark"
  55. tab1.Fields("Last Name").Value = "Hammond"
  56. tab1.Update()
  57. tab1.MoveFirst()
  58. # We do a simple bookmark test which tests our optimized VT_SAFEARRAY|VT_UI1 support.
  59. # The bookmark will be a buffer object - remember it for later.
  60. bk = tab1.Bookmark
  61. # Add a second record.
  62. tab1.AddNew()
  63. tab1.Fields("First Name").Value = "Second"
  64. tab1.Fields("Last Name").Value = "Person"
  65. tab1.Update()
  66. # Reset the bookmark to the one we saved.
  67. # But first check the test is actually doing something!
  68. tab1.MoveLast()
  69. if tab1.Fields("First Name").Value != "Second":
  70. raise RuntimeError("Unexpected record is last - makes bookmark test pointless!")
  71. tab1.Bookmark = bk
  72. if tab1.Bookmark != bk:
  73. raise RuntimeError("The bookmark data is not the same")
  74. if tab1.Fields("First Name").Value != "Mark":
  75. raise RuntimeError("The bookmark did not reset the record pointer correctly")
  76. return dbname
  77. def DoDumpAccessInfo(dbname):
  78. from . import daodump
  79. a = forms = None
  80. try:
  81. sys.stderr.write("Creating Access Application...\n")
  82. a=Dispatch("Access.Application")
  83. print("Opening database %s" % dbname)
  84. a.OpenCurrentDatabase(dbname)
  85. db = a.CurrentDb()
  86. daodump.DumpDB(db,1)
  87. forms = a.Forms
  88. print("There are %d forms open." % (len(forms)))
  89. # Uncommenting these lines means Access remains open.
  90. # for form in forms:
  91. # print " %s" % form.Name
  92. reports = a.Reports
  93. print("There are %d reports open" % (len(reports)))
  94. finally:
  95. if not a is None:
  96. sys.stderr.write("Closing database\n")
  97. try:
  98. a.CloseCurrentDatabase()
  99. except pythoncom.com_error:
  100. pass
  101. # Generate all the support we can.
  102. def GenerateSupport():
  103. # dao
  104. gencache.EnsureModule("{00025E01-0000-0000-C000-000000000046}", 0, 4, 0)
  105. # Access
  106. # gencache.EnsureModule("{4AFFC9A0-5F99-101B-AF4E-00AA003F0F07}", 0, 8, 0)
  107. gencache.EnsureDispatch("Access.Application")
  108. def DumpAccessInfo(dbname):
  109. amod = gencache.GetModuleForProgID("Access.Application")
  110. dmod = gencache.GetModuleForProgID("DAO.DBEngine.35")
  111. if amod is None and dmod is None:
  112. DoDumpAccessInfo(dbname)
  113. # Now generate all the support we can.
  114. GenerateSupport()
  115. else:
  116. sys.stderr.write("testAccess not doing dynamic test, as generated code already exists\n")
  117. # Now a generated version.
  118. DoDumpAccessInfo(dbname)
  119. def test(dbname = None):
  120. if dbname is None:
  121. # We need makepy support to create a database (just for the constants!)
  122. try:
  123. GenerateSupport()
  124. except pythoncom.com_error:
  125. print("*** Can not import the MSAccess type libraries - tests skipped")
  126. return
  127. dbname = CreateTestAccessDatabase()
  128. print("A test database at '%s' was created" % dbname)
  129. DumpAccessInfo(dbname)
  130. if __name__=='__main__':
  131. import sys
  132. from .util import CheckClean
  133. dbname = None
  134. if len(sys.argv)>1:
  135. dbname = sys.argv[1]
  136. test(dbname)
  137. CheckClean()