Figure 1 ps.pl

  
#!/usr/bin/perl

# ps.pl
# If this code works, it was written by Keith Brown.
# If not, it was written by Don Box.

use strict;

my $s = 'ps -ax';
my @a = split "\n", $s;

print <<HEADER;
Content-Type: text/xml

<xml xmlns:xdr='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
     xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
     xmlns:rowset='urn:schemas-microsoft-com:rowset'  
     xmlns:target='#RowsetSchema'>
  <xdr:Schema id='RowsetSchema'>
    <xdr:ElementType name='row' content='eltOnly' >
      <xdr:AttributeType name='PID' >
        <xdr:datatype dt:type='i4' rowset:dbtype='int' dt:maxLength='4' />
      </xdr:AttributeType>
      <xdr:AttributeType name='TTY' >
        <xdr:datatype dt:type='string' rowset:dbtype='str' 
                      dt:maxLength='10' />
      </xdr:AttributeType>
      <xdr:AttributeType name='TIME' >
        <xdr:datatype dt:type='string' rowset:dbtype='str' 
                      dt:maxLength='10' />
      </xdr:AttributeType>
      <xdr:AttributeType name='CMD' >
        <xdr:datatype dt:type='string' rowset:dbtype='str' 
                      dt:maxLength='80' />
      </xdr:AttributeType>
      <xdr:extends type='rowset:rowbase'/>
    </xdr:ElementType>
  </xdr:Schema>
  <rowset:data>
HEADER

for (my $i = 1; $i < @a; ++$i) {
  my @fields = split / +/, $a[$i];
  
  printf(qq[<target:row PID='%s' TTY='%s' TIME='%s' CMD='%s' />\n],
     @fields[1..@fields-1]);
}

print <<END
  </rowset:data>
</xml>
END

Figure 3 Form1.frm

  
VERSION 5.00
Object = "{CDE57A40-8B86-11D0-B3C6-00A0C90AEA82}#1.0#0"; "MSDATGRD.OCX"
Begin VB.Form Form1 
   Caption         =   "ADO Recordset Viewer"
   ClientHeight    =   6570
   ClientLeft      =   60
   ClientTop       =   345
   ClientWidth     =   7650
   LinkTopic       =   "Form1"
   ScaleHeight     =   6570
   ScaleWidth      =   7650
   StartUpPosition =   3  'Windows Default
   Begin VB.TextBox URL 
      Height          =   375
      Left            =   1680
      TabIndex        =   2
      Text            =   "https://soapl.develop.com/cgi-bin/ps.pl"
      Top             =   120
      Width           =   5655
   End
   Begin MSDataGridLib.DataGrid DataGrid1 
      Height          =   5655
      Left            =   120
      TabIndex        =   1
      Top             =   600
      Width           =   7335
      _ExtentX        =   12938
      _ExtentY        =   9975
      _Version        =   393216
      HeadLines       =   1
      RowHeight       =   15
      BeginProperty HeadFont {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
         Name            =   "MS Sans Serif"
         Size            =   8.25
         Charset         =   0
         Weight          =   400
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851} 
         Name            =   "MS Sans Serif"
         Size            =   8.25
         Charset         =   0
         Weight          =   400
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ColumnCount     =   2
      BeginProperty Column00 
         DataField       =   ""
         Caption         =   ""
         BeginProperty DataFormat {6D835690-900B-11D0-9484-00A0C91110ED} 
            Type            =   0
            Format          =   ""
            HaveTrueFalseNull=   0
            FirstDayOfWeek  =   0
            FirstWeekOfYear =   0
            LCID            =   1033
            SubFormatType   =   0
         EndProperty
      EndProperty
      BeginProperty Column01 
         DataField       =   ""
         Caption         =   ""
         BeginProperty DataFormat {6D835690-900B-11D0-9484-00A0C91110ED} 
            Type            =   0
            Format          =   ""
            HaveTrueFalseNull=   0
            FirstDayOfWeek  =   0
            FirstWeekOfYear =   0
            LCID            =   1033
            SubFormatType   =   0
         EndProperty
      EndProperty
      SplitCount      =   1
      BeginProperty Split0 
         BeginProperty Column00 
         EndProperty
         BeginProperty Column01 
         EndProperty
      EndProperty
   End
   Begin VB.CommandButton Refresh 
      Caption         =   "&Refresh"
      Height          =   375
      Left            =   120
      TabIndex        =   0
      Top             =   120
      Width           =   1455
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Dim rs As New ADODB.Recordset

Private Sub Refresh_Click()
  If (rs.State = ADODB.adStateOpen) Then
    rs.Close
  End If
  rs.Open URL.Text
  Set DataGrid1.DataSource = rs
End Sub

Private Sub Form_Resize()
  DataGrid1.Height = Form1.Height - 1100
  DataGrid1.Width = Form1.Width - 350
  URL.Width = Form1.Width - 1900
End Sub

Figure 4 get.asp

  
<script language='jscript' runat=Server>
// read authors from database
    var rs = Server.CreateObject("ADODB.Recordset");
    rs.LockType = 4; // batchOptimistic
    rs.Open("select * from authors", "Provider=SQLOLEDB;Initial 
            Catalog=pubs;UID=sa;PWD=");

// stream XML back as HTTP response
    Response.ContentType = "text/xml";
    Response.Write("<?xml version='1.0' ?>\n");    
    rs.Save(Response, 1);
</script>

Figure 6 update.js

  
// load recordset from HTTP server
var rs = new ActiveXObject("ADODB.Recordset");
rs.Open("https://localhost/get.asp");

// make one or more modifications
rs.Fields("au_lname") = "Box";
rs.MoveNext();
rs.Fields("au_lname") = "Box";

// serialize recordset to an XML dom
var dom = new ActiveXObject("MSXML.DOMDocument");
rs.Save(dom, 1);

// post back to HTTP server
var req = new ActiveXObject("Microsoft.XMLHTTP");
req.open("POST", "https://localhost/put.asp", false);
req.send(dom);

WScript.echo(req.responseText);

Figure 7 put.asp

  
<script language='jscript' runat=Server>
try
{
// read recordset from HTTP POST data in request
    var rs = Server.CreateObject("ADODB.Recordset");
    rs.Open(Request);

// establish connection to database
    var conn = Server.CreateObject("ADODB.Connection");
    conn.Open("Provider=SQLOLEDB;Initial Catalog=pubs;UID=sa;PWD=");
    conn.BeginTrans();
// send changes to database
    rs.ActiveConnection = conn;
    rs.UpdateBatch();
    conn.CommitTrans();
    Response.Write("Success!");
}
catch (e)
{
    conn.RollbackTrans();       
    Response.Write("Failure!");
}
</script>

Figure 8 rowset.xml

  
<xml xmlns:xdr="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
    xmlns:rowset="urn:schemas-microsoft-com:rowset" xmlns:target="#R">
<xdr:Schema id="R">
<xdr:ElementType name="row" content="eltOnly">
<xdr:AttributeType name="name" /> 
<xdr:AttributeType name="age" /> 
<xdr:extends type="rowset:rowbase" /> 
</xdr:ElementType>
</xdr:Schema>
<rowset:data>
<target:row name="Don" age="25" /> 
<target:row name="Aaron" age="20" /> 
</rowset:data>
</xml>

Figure 9 A Serialized Rowset

Namespace URI
Vocabulary
uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882
XML Data Reduced
uuid:C2F41010-65B3-11d1-A29F-00AA00C14882
XML Data Reduced Datatypes
urn:schemas-microsoft-com:rowset
OLE DB Persistence Provider Rowset

Figure 10 Predefined XDR Datatypes

ADO Type Enum
OLE DB DBTYPE
dt:type
rs:dbtype
dt:maxLength
rs:fixedLength
rs:long
adBigInt
I8
i8

8
TRUE

adBinary
BYTES
bin.hex

n


adBoolean
BOOL
Boolean

2
TRUE

adBSTR
BSTR
string

4294967295

TRUE
adChar
STR
string
str
n
TRUE

adCurrency
CY
i8
currency
8
TRUE

adDate
DATE
dateTime
variantdate
16
TRUE

adDBDate
DBDATE
date

6
TRUE

adDBTime
DBTIME
time

6
TRUE

adDBTimeStamp
DBTIMESTAMP
dateTime
timestamp
16
TRUE

adDecimal
DECIMAL
number
decimal
16
TRUE

adDouble
R8
float

8
TRUE

adFileTime
FILETIME
dateTime
filetime
16
TRUE

adGUID
GUID
uuid

16
TRUE

adInteger
I4
int

4
TRUE

adLongVarBinary
BYTES
bin.hex

n

TRUE
adLongVarChar
STR
string
str
n

TRUE
adLongVarWChar
WSTR
string

n

TRUE
adNumeric
NUMERIC
number
numeric
19
TRUE

adSingle
R4
r4

4
TRUE

adSmallInt
I2
i2

2
TRUE

adTinyInt
I1
i1

1
TRUE

adUnsignedBigInt
UI8
ui8

8
TRUE

adUnsignedInt
UI4
ui4

4
TRUE

adUnsignedSmallInt
UI2
ui2

2
TRUE

adUnsignedTinyInt
UI1
ui1

1
TRUE

adVarBinary
BYTES
bin.hex

n


adVarChar
STR
string
str
n


adVariant
VARIANT
string




adVarNumeric
VARNUMERIC
number
varnumeric
n
TRUE

adVarWChar
WSTR
string

n


adWChar
WSTR
string

n
TRUE

Figure 11 OLE DB Properties Serialized to XML

ADODB.Field Member
DBCOLUMNINFO Field
XML Attribute
Applies To
Name
pwszName
rs:name
AttributeType
Index (implicit)
iOrdinal
rs:number
AttributeType
Attributes
dwFlags
see Figure 12

DefinedSize
ulColumnSize
dt:maxLength
datatype
Type
wType
see Figure 13

Precision
bPrecision
rs:precision
datatype
NumericScale
bScale
rs:scale
datatype

Figure 12 OLE DB Attributes Serialized to XML

ADO FieldAttributeEnum
DBCOLUMNFLAGS
Attribute Name
Applies To
adFldMayDefer
MAYDEFER
rs:maydefer
AttributeType
adFldUpdatable
WRITE
rs:write
AttributeType
adFldUnknownUpdatable
WRITEUNKNOWN
rs:writeunknown
AttributeType
adFldFixed
ISFIXEDLENGTH
rs:fixedLength
datatype
adFldIsNullable
ISNULLABLE
rs:nullable
AttributeType
adFldMayBeNull
MAYBENULL
rs:maybenull
datatype
adFldLong
ISLONG
rs:long
datatype
adFldRowID
ISROWID
rs:rowid
AttributeType
adFldKeyColumn
KEYCOLUMN
rs:keycolumn
AttributeType

Figure 13 Column Properties Serialized to XML

ADO Field/OLE DB Column Property
XML Attribute
BASECOLUMNNAME
rs:basecolumn
BASETABLENAME
rs:basetable
BASECATALOGNAME
rs:basecatalog
BASESCHEMANAME
rs:baseschema
ISAUTOINCREMENT
rs:autoincrement

Figure 14 DBPROPSET_ADC Values

OLE DB Rowset Property
ElementType Attribute
Datatype
DBPROP_UPDATABILITY
updatable
Boolean
DBPROP_ADC_UPDATERESYNC
updateresync
i4
DBPROP_ADC_UNIQUETABLE
uniquetable
string
DBPROP_ADC_UNIQUESCHEMA
uniqueschema
string
DBPROP_ADC_UNIQUECATALOG
uniquecatalog
string
DBPROP_ADC_CUSTOMRESYNC
customresync
string
DBPROP_IRowsetChange
irowsetchange
Boolean
DBPROP_IRowsetUpdate
irowsetupdate
Boolean
DBPROP_COMMANDTIMEOUT
commandtimeout
i4
DBPROP_ADC_BATCHSIZE
batchsize
i4
DBPROP_ADC_UPDATECRITERIA
updatecriteria
i4
DBPROP_ADC_RESHAPENAME
reshapename
string
DBPROP_ADC_AUTORECALC
autorecalc
i4