P
Phlip
Accessories:
The canonic way to write "unit" tests for a database is this:
setUp
begin a transaction
create Sample Database
test_foo
select stuff in the database
assert it matches the samples
test_bar
update stuff in the database
select it back
assert it matches
tearDown
rollback the transaction
That's relatively efficient because transactions buffer everything with
miminal overhead. I want to do that to Access while I test a Form. And I
want to do it from VB Classic, not from VBA inside Access.
So let's set up an experiement to see how close we can get to that pattern.
Creae a form, paint a button, set up the References to Access and DAO, and
write this:
Private Sub Command1_Click()
Dim ax As New Access.Application
ax.Visible = False
ax.AutomationSecurity = msoAutomationSecurityLow
ax.OpenCurrentDatabase "database.mdb"
Dim cn As DAO.Database
Set cn = ax.CurrentDb
ax.DBEngine.BeginTrans
' beginning to build the sample database
cn.Execute "DELETE FROM DataTable"
ax.DoCmd.OpenForm FormName:="DataTable"
End Sub
The last line fails with the infamous 3008 error message, "The table
'DataTable' is already opened exclusively by another user, or it is already
open through the user interface and cannot be manipulated programmatically."
The .BeginTrans call did it. Without that line, I can delete the table and
open its form fine. (I intend to write test cases that mess with that form,
and its data, for the usual test-first benefits.)
The standard answer to 3008 is to turn off record locking. All our locking
here is off and optimistic.
To workaround, I can of course just fudge. I could manually build a
transaction by copying the DataTable to a backup table, then restore it
during tearDown(). Or I can let the test data polute the golden copy of the
database.
The question is this: Am I missing some tweak in the interaction of
BeginTrans and the Form architecture where I can have a real transaction,
and the Form can display data from that transaction transparently?
The canonic way to write "unit" tests for a database is this:
setUp
begin a transaction
create Sample Database
test_foo
select stuff in the database
assert it matches the samples
test_bar
update stuff in the database
select it back
assert it matches
tearDown
rollback the transaction
That's relatively efficient because transactions buffer everything with
miminal overhead. I want to do that to Access while I test a Form. And I
want to do it from VB Classic, not from VBA inside Access.
So let's set up an experiement to see how close we can get to that pattern.
Creae a form, paint a button, set up the References to Access and DAO, and
write this:
Private Sub Command1_Click()
Dim ax As New Access.Application
ax.Visible = False
ax.AutomationSecurity = msoAutomationSecurityLow
ax.OpenCurrentDatabase "database.mdb"
Dim cn As DAO.Database
Set cn = ax.CurrentDb
ax.DBEngine.BeginTrans
' beginning to build the sample database
cn.Execute "DELETE FROM DataTable"
ax.DoCmd.OpenForm FormName:="DataTable"
End Sub
The last line fails with the infamous 3008 error message, "The table
'DataTable' is already opened exclusively by another user, or it is already
open through the user interface and cannot be manipulated programmatically."
The .BeginTrans call did it. Without that line, I can delete the table and
open its form fine. (I intend to write test cases that mess with that form,
and its data, for the usual test-first benefits.)
The standard answer to 3008 is to turn off record locking. All our locking
here is off and optimistic.
To workaround, I can of course just fudge. I could manually build a
transaction by copying the DataTable to a backup table, then restore it
during tearDown(). Or I can let the test data polute the golden copy of the
database.
The question is this: Am I missing some tweak in the interaction of
BeginTrans and the Form architecture where I can have a real transaction,
and the Form can display data from that transaction transparently?