What’s new in ADO 2.5 Greg Hinkel Program Manager Data Access Group mdac@microsoft.com Agenda ADO - Overview Semi-structured Data ADO 2.5 - Programming Model URL binding for ADO Objects Record Object Stream Object Performance and XML Summary ADO Overview A single, powerful consumer interface for data exposed by OLE DB providers For use in Web-based, Client/Server and distributed applications Works with many languages (Visual Basic®, Visual C++®, Visual J++™, Visual Basic Scripting Edition) High Performance Simple Object Model Semi-structured data Data that is: More structured than a BLOB Structured differently than a relational database table Examples: A file system Email data An arbitrary XML stream Web pages Semi-structured data Data tends to be organized hierarchically, like a tree Each node in the tree has a set of properties Hierarchies have arbitrary depth Each node may have a unique set of properties Leaf-nodes associated with a special “Value” property Non-leaf nodes are collections of other nodes Semi-structured data: Requirements Node Operations Scoped Operations Move, Copy, Delete operations apply to all contained nodes Querying Get/Set properties, Add/Delete properties A list of nodes that satisfy a predicate on properties Lightweight Operations such as reading email properties, etc. are done many times ADO 2.5 - Design Goals Keep it simple! Allow ADO objects to be opened with URL strings Extend ADO to work with treestructured & hierarchical data sources Provide the ability to do scoped operations Extend ADO so that it may be used to read and manipulate binary streams Modeling semi-structured data with ADO 2.5 Collections are modeled as recordsets Nodes are modeled as a record object Common properties are modeled as fields of the recordset Folders, Directories Properties are modeled as fields of the record object Files, Email folder objects Contents of a record can be manipulated by the Stream object ADO 2.1 - Object Model Errors Command Connection Recordset Parameters ADO 2.5 - Object Model Errors Command Connection Recordset Record Parameters Fields Stream URL Naming for ADO URLs can be used to directly identify objects in a data source Record object represents a unique object nodes in a hierarchical namespace (files and folders) table in a relational database, unique rows in a table file, folder, table, row Recordset object represents the contents of a collection object rows of a table, files in a folder URL binding in ADO 2.5 ADO 2.5 allows URL naming for Connection, Recordset, Record, and Stream objects For a Recordset, URL must point to a collection type node For stream, URL must point to an object with a default stream defined The RootBinder cracks URLs and calls the right provider New record objects can also be created directly URL naming - sample code Sub RsOpen() Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset Dim rs1 as New ADODB.Recordset cn.Open “URL=http://server01/myfolder” rs1.Open “mysubfolder”, cn rs.Open “URL=http://server01/myfolder", , _ adOpenForwardOnly, _ adLockReadOnly End Sub Record Object (1 of 2) New automation object implemented in ADO 2.5 Models an entity that has a collection of properties and (possibly) nested entities Email, Files, web pages, structured documents, folders, XML node, Databases, Tables, etc. can also represent a row of a recordset Email/File contents appear as a stream property Record Object (2 of 2) Expresses the notion of containment & scoping Folders contain other folders and files Folder operations such as move, copy, etc. apply within the folder’s scope Properties are modeled as a collection of Fields Containment is modeled as Sub-Records Records can be viewed in a tabular form as a recordset Properties and methods are implemented to operate on the record object Opening a Record Object Many ways to open a record object Open directly using a URL that uniquely identifies it From an ADO recordset by specifying an individual record From a field’s value property Record object always exists in the context of a Connection object connection object is either implicitly created or explicitly specified Record Properties ActiveConnection Identifies the active connection object associated with the current record State Current state of the record object Source URL string used to open the record object Mode Access mode for the record object ParentURL URL string identifying the parent node of the current record object RecordType Type of the current record object – simple document, collection, structured document Record Methods Open Opens an existing record object or creates a new one using URL, a connection string, or a recordset object Close Closes an already open record object Cancel Cancels an aynchronous operation on the recordset CopyRecord Copies a sub-record and its children to a new location MoveRecord Moves a sub-record and its children to a new location DeleteRecord Deletes a sub-record and its children GetChildren Opens a recordset containing the child nodes of the current record object The Record Object ‘opens an existing record object or creates a new one Sub OpenFolderIfExists() Dim rec As New Record Dim rs As Recordset rec.Open "TestFolder", "URL=http://adot20/davfs/greghin/", , adOpenIfExists Or adCreateCollection Debug.Print "Record is Collection : " & Str(rec.RecordType) Debug.Print rec.CopyRecord(, "http://adot20/davfs/greghin/TestSubFolder") Set rs = rec.GetChildren While Not rs.EOF Debug.Print rs(0) rs.MoveNext Wend End Sub Fields of a Record object A field represents a property associated with a record object Title, size, modified time of a file, folder, email message Fields are implemented as a collection on the record object Methods and properties are same as that on recordset’s field object New fields can be added to the collection of an already open record object The Recordset Object When a record is a collection (such as a folder), it has other records contained in it A view of contained records is available as a recordset Use GetChildren method on the Record object opens the default contents recordset - predefined schema for document source providers Execute a command against a folder tabular view as opposed to the tree view Ability to search on properties Use Record and Recordset for navigation URL is one of the fields on the contents recordset & can be used to open the contained records Recordsets with Variable # of Columns Many data sources generate recordsets where each row has a different set of columns Case in point: Contents of a mail folder Case in point: An XML stream An email folder has different properties from the Contacts folder Each element may have a different set of attributes Case in point: The Contents recordset Each file in a folder has different set of properties Supporting Variable Column Recordsets The fields collection on the recordset contains the set of “common” fields Each record has a set of fields unique to that row From address, subject, receive date, etc. for email File name, size, last modified, etc. for files This is a superset of the common columns that exist for the recordset To view the variable fields, obtain a record object from the recordset and then use its fields collection Relationship between the Record & Recordset Objects Record’s field collection It is possible to add/delete fields from an already open record object Superset of the fields collection on the associated source recordset, if any only for fields that are unique to that record Record behaves in the same update mode as its source recordset if no source recordset, then in immediate update mode Working with the Recordset Object 'open Recordset Sub OpenRecordset() Dim rs As New ADODB.Recordset Dim rec As New ADODB.Record Dim cn As New ADODB.Connection stSrc = "http://server02/myfolder/testfolder" rs.Open stSrc, , _ adOpenForwardOnly, _ adLockReadOnly, _ adCmdURLBind rs.MoveNext rec.Open rs End Sub Working with the Fields collection Sub RSFields() Dim rs As New Recordset Dim rec as new Record stURL = "http://server01/myfolder" rs.Open stURL, , , , adCmdURLBind while rs.eof <> True rec.Open rs For i = 0 To rec.Fields.Count - 1 Debug.Print rec.fields(I).name, “=“, _ rec.fields(I).value Next I rs.MoveNext Wend End Sub Stream Object A new ADO 2.5 object An automation object used to manipulate the contents of a binary/textual stream Implemented on top of IStream interface Record objects usually have a default stream associated with them content of an email message, default document for a web folder BLOB/Text fields in a database may also be viewed as a stream object Stream Properties Size Total size of the stream in number of bytes EOS Identifies if cursor is currently positioned at end of stream Position Offset is bytes of current position from beginning of stream Type Identifies the type of data in the stream Lineseparator Identifies the line separator character in textual streams State Identifies the current state of the stream object Stream Methods (1 of 3) Open Opens an exisiting stream object from a URL or a record object Close Closes an already open stream object Cancel Cancels an aynchronous operation on the a stream object Open ([Source as variant], [Mode as ModeEnum = adoModeUnknown], [Options as StreamOpenOptionsEnum = adOpenFromURL], [uid as string], [pwd as string]) Stream Methods (2 of 3) Read ReadText Reads specified number of bytes or characters from a stream Write WriteText Writes the specified text or binary stream into the stream object starting from the current position For textual streams, skips an entire line of characters SkipLine SetEOS Sets the “end of Stream” character. Truncates all the remaining data. Flush Flushes the contents of a stream to the underlying object that it is bound to (implementor of Istream) ReadText ([NumChar as long = adReadAll]) as String WriteText (StrChars as string, [Options as StreamWriteOptionsEnum = adWriteChar]) Stream Methods (3 of 3) CopyTo Copies a specified number of bytes or characters from a stream to another stream object LoadfromFile Loads the contents of a file by reading in data from an existing file Saves the contents of a stream into a specified file SaveToFile CopyTo(destStream as stream, [NumChars as integer = 1]) LoadFromFile (strFileName as string) SaveToFile(FileName as string, [SaveOptions as SaveOptionsEnum = adSaveCreateNotExist]) Working with the Stream object Sub StmOperations() Dim Stm as New ADODB.Stream stURL = "http://server01/myfolder/mydoc.doc" Stm.Open stURL Debug.Print Stm.Size Debug.Print Stm.Type Debug.Print Stm.ReadText Stm.SaveToFile “c:\my documents\copyofmydoc.doc” End Sub ADO 2.5 - Summary Extends core ADO to work with semistructured data exposed by new data sources Enables web-publishing and document management through scripting languages Shipping in MDAC 2.5 with Windows 2000 Will be available in Beta3 Performance ADO 2.5 is faster than ADO 2.1 We wrote our own IDispatch for scripting languages Much better on multiple processor machines XML rs.Save Response, adPersistXML rs.Open Request Questions?