Database system with methods providing a platform-independent self-describing data packet for transmitting information6151602Abstract A three-tier data processing system of the present invention includes a client application, operating on a client machine (i.e., first tier), which obtains data from a back-end data source (e.g., database server) by submitting a request (e.g., SQL query) to a middle tier. The middle tier, in turn, comprises a provider and a resolver. Data is actually returned to the client by means of a "data packet" of the present invention, which is a platform-independent self-describing data format used to exchange data between different subsystems of the architecture. A data packet normally represents a result set, which is received by a client from a remote server, containing both data and metadata. Upon receiving the data packet from the provider, the client unpacks the data and then proceeds to process and manipulate the data as if it were local data (e.g., for insert, deletes, updates, and the like). Additional data packets are provided for special purpose use, including a "delta" data packet, used when applying client updates, and an "error" data packet, used to report results (including errors, after a failed update attempt) back to a client. The resolver, upon receiving a delta data packet, applies logic for effecting the user-specified modifications to the data set present at the back end. In the event that the resolver is unable to apply the user-specified modifications, it reports the failed operation back to the client via an error data packet. Claims What is claimed is: Description COPYRIGHT NOTICE
TABLE 1
______________________________________
Intrinsic types
Type Description
______________________________________
Int8 8-bit unsigned integer.
Int16 16-bit unsigned integer.
Int32 32-bit unsigned integer.
String String stored as a length byte followed by that many characters.
______________________________________
All multi-byte values in a data packet (e.g., 16- and 32-bit integers) are stored in little endian format (i.e., least significant byte first). The data types of columns and optional parameters in a data packet are defined through 32-bit type descriptors. Table 2 below shows the layout of a type descriptor.
TABLE 2
__________________________________________________________________________
Type descriptor format
Bits Meaning
Description
__________________________________________________________________________
0 . . . 15
Size Size indicator (1 . . . 64k). For a fixed size type this field
gives the
size in bytes of the data. For a varying size type this field
gives the size in bytes (1, 2, or 4) of the byte count (8-,
16-, or
32-bit) that prefixes the data.
16 . . . 21 Type Type indicator (0 . . . 63). This field indicates how
the data should
be interpreted.
22 Varying 0 = Fixed size type, 1 = Varying size type. For a fixed size
type, the Size field gives the size in bytes of the data. For a
varying size type, the Size field gives the size in bytes
(1, 2, or
4) of the length indicator that prefixes the data.
23 Array 0 = Single element, 1 = Array. For an array, the data consists
of a 32-bit element count followed by that many elements.
24 . . . 31 Unused
__________________________________________________________________________
Type descriptors are structured such that an implementation can learn the size of the data of a given type without understanding how the data is actually interpreted. Two basic categories of data types are provided: fixed-sized and varying-sized types. Fixed-size types include, for instance, integers and floats. Varying-size types include, for instance, strings and blobs. In the current embodiment, data of a fixed size type can occupy between 1 and 64 k bytes. Data of a varying size type can occupy up to 4 GB, and is always prefixed by an 8-, 16-, or 32-bit length indicator that specifies the actual size of the data that follows. For an array data type, the actual data consists of a 32-bit element count followed by that many elements. The data of each element is formatted according to the type descriptor. The Type field of a type descriptor indicates how the data should be interpreted. Table 3 lists the defined type codes.
TABLE 3
__________________________________________________________________________
Type codes
Name Value
Type Description
__________________________________________________________________________
dsfldUNKNOWN
0 Unknown Unknown format.
dsfldINT 1 Signed integer Size must be 1, 2, 4, or 8.
dsfldUINT 2 Unsigned integer Size must be 1, 2, 4, or 8.
dsfldBOOL 3 Boolean Size must be 1, 2, 4.
dsfldFLOATIEEE 4 IEEE float Size must be 4 (Single), 8 (Double), or 10
(Extended).
dsfldBCD 5 BCD Used for BDEfldBCD. Precision and decimals
are given as optional parameters. (szWIDTH,
szDECIMALS).
dsfldDATE 6 Date Size must be 4. Used for BDEfldDATE.
dsfldTIME 7 Time Size must be 4. Used for BDEfldTIME.
dsfldTIMESTAMP 8 Timestamp Size must be 8. Used for BDEfldTIMESTAMP.
dsfldZSTRING 9 Multi-byte string Used for BDEfldZSTRI
NG. Varying field with
1 or 2-byte length prefix. Field-width is given
as optional parameter (szWIDTH).
dsfldUNICODE 10 Unicode string Size is in bytes and therefore always
even.
Varying field with 1 or 2-byte length prefix.
Field-width is given as optional parameter
(szWIDTH).
dsfldBYTES 11 Bytes Used for BDEfldBYTES, fldVARBYTES, and
fldBLOB.
FldBYTES is fixed-length.fldVARBYTES is
variable length, with a 1 or 2-byte length
prefix.fldBLOB is variable length, with a 4-
byte length prefix. The subtype, if any, is given
as optional parameter (SzSUBTYPE).
Field-width is given as optional parameter
(szWIDTH) forfldBYTES and fldVARBYTES.
__________________________________________________________________________
Table 4 below lists a set of type codes and the corresponding data formats.
TABLE 4
______________________________________
Type code examples
Type code Data format
______________________________________
0.times.00010001
1 byte to be interpreted as an 8-bit signed integer.
0.times.00020004 4 bytes to be interpreted as a 32-bit unsigned
integer.
0.times.00490001 1 byte length indicator followed by that many bytes of
data to be interpreted as a multi-byte string value.
0.times.004A0002 2 byte length indicator followed by that many bytes of
data to be interpreted as a Unicode string (with half as
many Unicode characters).
0.times.004B0004 4 byte length indicator followed by that many bytes of
data to be interpreted as a block of bytes.
0.times.00820002 4 byte element count followed by that many 1 6-bit
unsigned integers.
______________________________________
D. Data Packet Header Layout As previously mentioned, the first section of a data packet is the data packet header (i.e., header 410). The layout of a data packet header in the currently-preferred embodiment is illustrated by table 5 below.
TABLE 5
______________________________________
Data packet header layout
Name Type Description
______________________________________
iMagicCookie
Int32 Magic number (0.times.BDE01996). Identifies
this as a data packet in WINTBL format
(little endian).
iMajorVer Int16 Major version number (1).
iMinorVer Int16 Minor version number (0).
iHeaderSize Int32 Size of fixed part of header in bytes (24).
iColCount Int16 Column count.
Int16 Reserved (0).
iRowCount Int32 Row count. (0 if unknown, or if
data packet only contains metadata).
iProperties Int32 pcklpropsMETADATA.sub.-- INCL (1):
Metadata (field descriptors, optional
parameters) are included.
Column descriptor section.
______________________________________
Here, the iMagicCookie field allows quick validation of a data packet by checking that the first four bytes of the image contain the expected value. By including a iHeaderSize field in the header, additional fields can be added to the fixed part of the header in future versions. The beginning of the column descriptor section (described below) is found by adding the iHeaderSize field to the beginning of the header. The iColCount and iRowCount fields give the number of columns and rows in the data packet. The data packet might not contain any metadata (column descriptors, and/or optional parameters) if it is a partial data packet (i.e., iProperties contains the pcklpropsMETADATA.sub.-- INCL bit). The first data packet in a series of partial data packets, should contain metadata information, but does not need to contain any data. E. Column Descriptors The data packet header is followed by a list of column descriptors, if the pcklpropsMETADATA.sub.-- INCL bit is set in iProperties. The iColCount field in the header specifies the number of column descriptors that follows the header. The format of each column descriptor is given by table 6 below.
TABLE 6
______________________________________
Column descriptor layout
Name Type Description
______________________________________
szColName String Column name.
IcolType Int32 Column type.
IcolAttr Int16 Column attributes.
Optional parameters section.
______________________________________
Here, the szColName is a unique name, identifying the column. The iColType field is a 32-bit type descriptor of the form (see Type descriptor format table above). The iColAttr field is a set of bit-flags representing common field attributes, as shown in table 7.
TABLE 7
______________________________________
Column attributes
Name Value Description
______________________________________
fldAttrHIDDEN
0.times.0001
Column is hidden.
fldAttrREADONLY 0.times.0002 Column is read-only.
fldAttrREQUIRED 0.times.0004 Column requires a value (null value not
allowed).
______________________________________
Each column descriptor is followed by a separate optional parameters section (described below), that relates to that column only. F. Optional Parameter Sections As previously mentioned, a data packet includes an area called the optional parameters section, following the column descriptor section, which contains additional metadata information, like constraints, data-ordering information, and the like. In addition, each column descriptor is followed by an (possibly empty) optional parameters section. In an exemplary embodiment, an optional parameters section comprises a 16-bit parameter count followed by that many optional parameters, as is illustrated by the following table.
TABLE 8
______________________________________
Optional parameters section layout
Name Type Description
______________________________________
iParCount Int16 Optional parameter count.
Optional parameters.
______________________________________
An empty optional parameters section simply consists of a 16-bit zero. The layout of each optional parameter in a non-empty optional parameters section is given by table 9.
TABLE 9
______________________________________
Optional parameter layout
Name Type Description
______________________________________
szParName String Parameter name.
iParType Int32 Parameter type (Type descriptor)
Parameter value(s)
______________________________________
The iparType field is a 32-bit type descriptor of the form (see, "Type descriptors" above). It is immediately followed by the actual parameter data. A list of predefined optional parameters is described below. G. Row Data The final section of a data packet is the row data. The iRowCount field in the header specifies the number of row data entries that follow the optional parameters. The format of each row data entry is given by table 10.
TABLE 10
______________________________________
Row data layout
Name Type Description
______________________________________
iRowStatus Int8 Row status.
InullBits Int8[ ] Null indicator bit array.
Data.
______________________________________
The RowStatus column contains a row status indicator. The RowStatus is used to indicate editing done to the data in the original data packet. Possible values are as follows.
TABLE 11
______________________________________
Row status values
Name Value Description
______________________________________
dsRecNotModified
0x00 Unmodified `original` row.
dsRecOrg 0x01 Original version of modified row.
dsRecDeleted 0x02 Deleted row.
dsRecNew 0x04 Inserted row.
dsRecModified 0x08 Modified row.
dsRecunused 0x20 Unused row.
______________________________________
When a row has been modified, a new version of that row with the changes is added, and the original row gets a RowStatus value of dsRecOrg. The modified row gets the value dsRecModified. If a row has been deleted, or inserted, they get the value dsRecDeleted or dsRecNew. The RowStatus values can be combined to reflect multiple modifications to the same row, such as when a modified record is modified again or an inserted record is deleted. In the first case, the original row would have a RowStatus value of dsRecOrg, the modified row with the first change would have the value dsRecOrc+dsRecModified, and the modified row with the second change would have the value dsRecModified. In the second case, the RowStatus value would be dsRecNew+dsRecDeleted. In general, in order to see the most current version of the rows, the RowStatus can be tested against dsISVISIBLE=NOT (dsRecDeleted+dsRecOrg+dsRecuUnUsed). The iNullBits field is a bit array with two-times iColCount entries. The two least significant bits (0.times.01, 0.times.02) of the first byte correspond to the first column, the next two bits (0.times.04, 0.times.08) correspond to the second column, and so on for the first eight columns. The following bytes (if any) represent groups of eight columns in the same fashion. The total number of bytes occupied by the iNullBits field is (2*iColCount+7) div 8. If any of the 2 bits for a given column is set, the column is blank (null). Otherwise, if both the bits for a given column are clear (0), the column is not blank. The 2 bits for each value is used to distinguish between an actual NULL-value (1), and a special state of "unchanged" (2), as compared to a value in some other row, which makes it unnecessary to include it in the data packet (see e.g., delta data packet description). Possible blank-values are illustrated by the following table.
TABLE 12
______________________________________
Lists the possible blank-values
NullBits (for each column)
Value Description
______________________________________
NO.sub.-- BLANK
0 Contains non-Null value.
BLANK.sub.-- NULL 1 Contains Null-value.
BLANK.sub.-- UNCHANGED 2 Contains `unchanged` Null-value.
______________________________________
The iNullBits field is followed by the actual data for the row. The data consists of an entry for each non-null column, the format of which is given by the iColType field in the corresponding column descriptor. Notice that if a column is null, no data is present for that column. Each of the iRowStatus and iNullBits fields does not have a corresponding column descriptor; they are not counted in the iColCount field, since they are always present. H. Predefined Optional Parameters In the currently-preferred embodiment, optional parameters include the following.
TABLE 13
__________________________________________________________________________
Predefined optional parameters.
Attribute name
Type descriptor
Description
__________________________________________________________________________
szDEFAULT.sub.-- ORDER
dsfldUINT
Describes the order of the data
Int16[ ] rows, if any.
The array contains the column
numbers of the columns used to
order the data. The column
numbers are 1 -based, and are
contained in the lower 12-bit of
each integer. The upper 4 bits
are used to indicate special
attributes for the column ordering,
like whether the column is case-
insensitive, or is sorted in
descending order. This parameter
allows the data in a data packet to
be viewed and inserted in the order
of the original data. It can be
combined with the
szUNIQUE.sub.-- KEY parameter to
simulate a primary index.
szUNIQUE.sub.-- KEY dsfldUINT Describes a set of columns in the
Int16[ ] data rows, that must be considered
unique. The column numbers are
1 -based.
This parameter allows the update-
semantics of a unique key to be
enforced on the data in a data
packet. More than one unique key
can be specified.
szCHANGE.sub.-- LOG dsfldUINT Describes the editing changes
Int32[ ] made to the data in a data packet,
if any. Each edit consists of a
series of 3 integers, with the
following format:
<RowNo1><RowNo2><EditActio
n>
where RowNo1 indicates the row
(1 -based) that was edited, RowNo2
is the new version of the row (if
any), and EditAction is one of the
following: dsRecModified,
dsRecDeleted, or dsRecNew.
This parameter makes it possible
to undo changes in the reverse
order in which they were applied.
szSERVER.sub.-- COL dsfldZSTRING Name of collation sequence used
String to order data, if any. Informational
only.
sZLCID dsfldUINT LCID or language driver used to
Int32 order the data. (typically,
Windows specific).
This parameter allows the data in a
data packet to be ordered using the
collation sequence of the original
data source.
szREADONLY dsfldBOOL If True (1), indicates that the data
Bool16 in the data packet is not
updateable.
szWIDTH dsfldUINT Column optional parameter for
Int16 variable length columns, is used to
describe the (maximum) width of
a column. Similar to iUnits1 in
BDE.
szDECIMALS dsfldUINT Column optional parameter for
Int16 fixed decimal type columns
(BCD). Similar to iUnits2 in BDE.
szSUBTYPE dsfldZSTRING Column optional parameter to
String describe the subtype of a column.
Similar to iSubType in BDE.
szDATASET.sub.-- DELTA dsfldBOOL If True (1), indicates that the data
Bool16 packet is a Delta-data packet, and
is subject to special semantics.
szDATASET.sub.-- CONTEXT dsfldBYTES This parameter carries
Int8[ ] information, that can be used when
resolving a Delta-data packet
update request
The information is application
specific.
szBDEDOMX dsfldBYTES Contains description of domain
Int8[ ] constraints.
This parameter allows for domain
constraints to be enforced on the
data in a data packet, in the same
manner they would be enforced at
the original data source.
The description is BDE specific.
szBDERECX dsfldBYTES Contains description of record
Int8[ ] constraints.
This parameter allows for record
constraints to be enforced on the
data in a data packet, in the same
manor they would be enforced at
the original data source.
The description is BDE specific.
szBDEDEFX dsfldBYTES Contains description default
Int8[ ] values.
This parameter allows for default
values to be used when adding a
new row to the data in a data
packet. The description is BDE
specific.
szAUTOINCVALUE dsfldINT Indicates the next value to use in a
Int32 column of the type autoincrement,
in case a new row is inserted.
This parameter can be used to
simulate the semantics of an
autoincrement field.
__________________________________________________________________________
I. Delta Data Packet The "delta" data packet describes updates made to data from an original data packet. These updates are in a form that allows a resolver to apply them to the original data source. The updates are contained in the data rows, and the update action (modify/inserted/deleted) are indicated using the RowStatus column. The column descriptors are identical to the ones in the original data packet. The following table outlines how the data is interpreted.
TABLE 14
__________________________________________________________________________
Updates contained in a delta data packet.
Update request
RowStatus value
Description of data in row
__________________________________________________________________________
Deleted
dsRecDeleted
The row contains all values and Nulls from the
original row, with the possible exception of fields that
are not needed in order to find the original row on the
server, and/or are too big (like blob-fields). Field
values which are not included, has the special blank-
value of BLANK.sub.-- UNCHANGED (2).
For these fields, the resolver will not be able to detect
whether another user changed them or not (which
could be considered an error).
Inserted dsRecNew The row contains values (or blanks) for all the
fields.
Modified dsRecorg The row contains all values from the original row,
with the same exceptions as mentioned above for
deletion. This row is always followed immediately by
a row with the RowStatus of dsRecModified.
dsRecModified This row only contains values (and Nulls) for the
fields that was changed as compared to the original
row. All other fields have the special blank-value of
BLANK.sub.-- UNCHANGED.
__________________________________________________________________________
The delta data packet contains one row for each Delete and Insert request, and two rows for each Modify request. The order of the rows should preferably be the same as the order in which the updates were performed by the client. In order to simplify the update actions that the server is supposed to execute, the currently-preferred embodiment restricts a delta packet from being partial or being updated (so that it does not contain optional parameters describing update-semantics, the edit-log, or any ordering information, that was part of the original data packet). In this manner, complexities involving processing of edit-log or ordering information for a delta packet are avoided. J. Error Data Packet The error data packet is returned from a resolver to report the results, including informing the client of an update request failure. The error data packet contains one row for each failed update-request. The rows have a number of predefined columns, followed by all the columns of the original data packet. The latter are used to return the values of a conflicting row, if any, to the client. The following table outlines the meaning of the predefined columns used for error data packets.
TABLE 15
__________________________________________________________________________
Layout of error data packet.
Column
Column name
Type
Column description
__________________________________________________________________________
1 szdsERRRECORDNO
Int32
Row number (1-based) of row in Delta-data
packet, that failed.
2 szdsERRRESPONSE Int32 Resolver responded with this action: Skip,
Abort, Merge,
3 szdsERRMESSAGE String The message associated with the failure.
4 szdsERRCONTEXT String Additional context, if any.
5 szdsERRCATEGORY Int32 The error category.
6 szdsERRCODE Int32 The native errorcode.
7 . . . n The columns of the original data packet. If any
of these fields contains a value other than
NULL(1), including BLANK.sub.-- UNCHANGED.
__________________________________________________________________________
K. Partial Data Packets In a "partial" data packet the total data content is divided into multiple data packets. In order to reduce overhead, only the first data packet contains metadata describing the data. The subsequent data packets merely contain the fixed size header and actual data contained in data-rows. The iProperties of the fixed size header, indicates whether a data packet contains metadata or not (pcklpropsMETADATA.sub.-- INCL). L. Creation of Data Packets In order to promote compatibility, a standardized interface for the creation of data packets is preferred, as represented by the following application programming interface (API). //Add an optional parameter DBIResult AddAttribute (PCKLATTRArea eAttrArea, pCHAR pszAttr, UINT32 iType, UINT32 iLen, pBYTE pValue); //Return pointer to the finished `safearray` DBIResult GetData packet (SAFEARRAY **ppSa); // Get the size of the safearray. DBIResult GetSize(pUINT32 piData packetSize); // Add this field to the data stream. DBIResult PutField (PCKLFldStauts eFldStatus, UINT32 iLhen, pBYTE pSrc); // Add a column descriptor. DBIResult AddColumnDesc (pDSData packetFLDDesc pFldDes); M. Reading of Data Packets In order to promote compatibility, a standardized interface for the reading of data packets is proposed, as represented by the following application programming interface (API). // Adds additional `partial` data packet for extraction DBIResult AddData packet(SAFEARRAY *pdatapacket); // Extract the next column descriptor. DBIResult GetColumnDesc (pDSData packetFLDDesc pFldDes); // Extract length of next attribute DBIResult GetAttributeLength (pUINT32 piLenqth); // Extract next attribute DBIResult GetNextAttribute (pCHAR pszAttribute, pUINT32 piType, pUINT32 piLen, pBYTE pValue); // Get length of next field DBIResult GetFieldLength (pUINT32 piLength); // Extract next field DBIResult GetField (pUINT32 piLength, pBYTE pValue, pBOOL pblank); N. Data Packet Support of Briefcase Model The data packet of the present invention can be "persisted"--that is, written out to disk as a persistent image. By embedding the deltas within the data packet, the system can persist the data set even after updates have been made. Applying the well-known "Briefcase model" (e.g., as provided by Windows 95 and described by the on-line help therein, under "Briefcase"), the user can disconnect the client from the network and still access the data. Specifically, the user saves a remote data set to local disk (e.g., on a laptop computer) and disconnects from the network. Nevertheless, the user can still edit the data at a remote location without connecting to the network. At a convenient point in time, the user can reconnect to the network and update the database accordingly. Here, the user's machine does not have to actually be connected to the server at all times in order for the user to work with the data. This allows the client to operate remotely from the data source and is, thus, ideal for laptop users or for sites where minimum network or database traffic is desired. O. Summary of Overall Methodology Referring now to FIG. 5, a flow chart 500 summarizing the overall methodology of the present invention is illustrated. At step 501, a client generates a request (e.g., SQL statement) for data from a data source, such as a relational database table stored on a back end server. In response to this request, at step 502, the provider accesses the data from the data source; it may now proceed to construct a data packet. In particular, the provider creates a data packet header comprising a metadata and optional parameters. Since stream I/O is employed, the provider can sequentially read column descriptor information from the data source (e.g., cursor handle on a result table) and then stream out corresponding metadata. After the column descriptor information has been added to the stream, at step 503, the provider proceeds to gather other information, such as relevant indexes and constraints (e.g., from the cursor). This information is added one by one to the stream as optional parameters, at step 504. In an exemplary embodiment, each attribute is added in the form of an attribute name following by an attribute value (e.g., as it in the manner used for Microsoft Windows .ini file). After all attribute information has been streamed out, the system may begin reading and processing actual data. Processing of actual data also occurs sequentially, as the information is being written out to the stream. In particular, the system loops through all data records of the result set and writes or streams out the corresponding field values, at step 505. Here, only actual data up is written out. Since the client can correctly interpret the stream from the descriptors, empty fields (e.g., ones containing padding) are not written out. After all fields of all records have been processed, a special value is written to the stream for indicating the "end of stream," at step 506. At this point, the system returns a handle for the stream, at step 507, which can be passed off to other parts of the system (e.g., network transport). At this point, the memory containing the data packet stream can be treated generically, including writing the data packet to disk. Since the data packet is a stream, it can be simply re-directed to disk, for retrieval at a later time. Processing at the client occurs in a similar manner, on a first-in, first-out basis, as indicated by flow chart 600 in FIG. 6. After the data packet is transmitted to the client, at step 601, the client starts the unpacking process by reading the data packet header for processing the column descriptors (step 602) and optional parameters (step 603). With this information, the client can set up a local data store for receiving the actual data, as indicated at step 604. Thereafter, the client can proceed to process the individual data records, at step 605, using the metadata information for correctly interpreting the stream. In this manner, the data is correctly reconstituted at the client (e.g., in a local data store). Processing of the stream itself terminates upon encountering the "end of stream" token, at step 606. Now, the data exists at the client and the data packet may be discarded. From the point of view of the client application, the data appears the same as if it were a local table. The client at this point would typically return a handle or cursor to a local table, for receiving updates from that client, as shown in step 607. In addition to the regular data packet outlined above, the system employs a "partial" data packet in those instances where it is necessary to spread the data out among multiple data packets. Consider, for instance, a scenario where the client only desires the first 50 data records of a result set. Here, a regular data packet can be sent to the client containing those first 50 records. Should the client then request the next 50 records (e.g., "fetch next"), a partial data packet can be sent containing only those next data records; in particular, the metadata information is not transmitted since the context is already known at that time. Once the data is at the client, it is subject to one of three operations or actions: insert, delete, and modify. Each of these actions creates data up for the delta data packet. For instance, an insert action creates an insert record indicating those records which have been inserted at the client. A delete action, on the hand, creates a record which includes the original data, so that the resolver can locate the original data record (present on the back end). The resolver can determine whether the data record has already been changed by another client by performing a field-by-field comparison for the record. In this manner, the resolver can re-examine data records on the back end for determining whether they have been already changed by another client. If a record has already been modified or deleted by another client, the resolver reports the error via an error data packet, for notifying the client of the condition. In the case of a modify action, the system transmits two records: the original data record and the new, modified data record. The transmission is optimized, however, to only transmit those fields in the modified data record which have changed (as compared to the original record). In a manner similar to that done for the delete action, the resolver examines the data record present on the back end for determining which fields have been modified by another client. Depending on desired implementation, resolver logic can be applied for accepting or rejecting client modifications to particular field values, based on previously-made modifications by another client. In a typical implementation, modifications of the client would be accepted if they do not conflict with previously-made modifications of another client (i.e., ones made to fields other than those modified by the posting client). Otherwise, feedback information is provided to the client so that the client can decide how to proceed (e.g., supply new modifications or cancel the operation). In the currently-preferred embodiment, the delta data packet transmits data records which contain records IDs identifying their particular type. A delete record, for example, includes a record ID of type "delete", followed by relevant values (i.e., the original data record, as described above for a delete record). With this approach, the delta data packet can be unpacked using the same mechanism for unpacking a regular data packet. While the invention is described in some detail with specific reference to a single-preferred embodiment and certain alternatives, there is no intent to limit the invention to that particular embodiment or those specific alternatives. Thus, the true scope of the present invention is not limited to any one of the foregoing exemplary embodiments but is instead defined by the appended claims.
|
Same subclass Same class Consider this |
||||||||||
