ADOxtra for Macromedia Shockwave Multiuser ServerBasic concepts of ADOxtra_MUS
The basic idea of ADOxtra_MUS is keeping a set of live ADO objects during the movie session. ADOxtra creates these objects within the MUS xtra's configuration procedure. Xtra provides an access to these objects via usual MUS messaging scheme. So the xtra makes ADO objects accessible to both client side movies and server side Lingo.
There are two most common types of ADO objects: ADODB.Connection and ADODB.Recordset. The Connection object defines a data source, while Recordset is used for actual data queries. These ADO objects are wrapped by ADOxtra's DataSource and Query objects respectively. Query object is the most common target for ADOxtra messages.
DataSource object keeps a reference to the wrapped Connection, which is used to establish a connection with particular database. DataSource object keeps track of attached Query objects. In other words, Query object is always defined in the context of the particular DataSource. To identify a Query as the message target ADOxtra uses the subject of a message. It has to consist of DataSource name followed by Query name separated by dot:
sendNetMessage( gConnection, "System.ADO.GetData", "SomeDataSource.SomeQuery", [:], 0 )
The Query object keeps a reference to the wrapped Recordset that is used for databasing operations. By default, the xtra does not try to reopen the Recordset every time it gets the data request. Instead it checks whether the Recordset's source matches the requested data. If so, it applies the requested filter and sends a response with the requested data. This approach is quite effective for applications that often read some subsets of a common rarely changed data.
For example, compare two different approaches below. Let us say we have a number of users in Users table with primary key UserId.
We can define a Query SpecificUser as below:
#Here we create a Query object with name SpecificUser
XtraCommand = "Query: SpecificUser"
#Make it available to MUS client movies
XtraCommand = "AccessMode: Normal"
#We do not usually want clients to be able to overwrite the SQL of this object
XtraCommand = "UseSQL: Predefined"
#Define SQL query with formal parameter UserId
XtraCommand = "ADO.SQL: SELECT * FROM Users WHERE UserId=<%UserId%>"
#Use static cursor for the recordset
XtraCommand = "ADO.CursorType: adOpenStatic"
#Use ADO client cursor
XtraCommand = "ADO.CursorLocation: adUseClient"
#Put a read only lock
XtraCommand = "ADO.LockType: adLockReadOnly"
Now let us define a Query AllUsers as below:
#Here we create a Query object with name AllUsers
XtraCommand = "Query: AllUsers "
#Make it available to MUS client movies
XtraCommand = "AccessMode: Normal"
#We do not usually want clients to be able to overwrite the SQL of this object
XtraCommand = "UseSQL: Predefined"
#Define SQL query with formal parameter ParentId
XtraCommand = "ADO.SQL: SELECT * FROM Users"
#Use static cursor for the recordset
XtraCommand = "ADO.CursorType: adOpenStatic"
#Use ADO client cursor
XtraCommand = "ADO.CursorLocation: adUseClient"
#Put a read only lock
XtraCommand = "ADO.LockType: adLockReadOnly"
The query AllUsers is almost the same except for ADO.SQL setting.
Now we can get the data about User with UserId = 10. The SpecificUser query could be used in this way (client side):
sendNetMessage( gConnection, "System.ADO.GetData", "DataSource.SpecificUser", [#QueryParams:[#UserId:10]], 0 )
This message will cause ADOxtra 's query object to close the recordset and reopen it again with new SQL source.
The AllUsers query could be used in the other way (client side):
sendNetMessage( gConnection, "System.ADO.GetData", "DataSource.AllUsers", [#Filter:"UserId=1"], 0 )
While processing this message ADOxtra will not try to requery the whole recordset. Instead, it applies the specified filter to Recordset's Filter property and replies with filtered data returned by recordset.
You may force closing recordset after processing message by specifying #Close:1 property in a message contents property list:
sendNetMessage( gConnection, "System.ADO.GetData", "DataSource.AllUsers", [#Filter:"UserId=1", #Close:1], 0 )
|