Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.


Skip to first unread message


May 20, 2003, 4:31:47 AM5/20/03
Can someone give me a brief idea about the organisation of

And what are the APIs available to access CE DB.

Maarten Struys

May 21, 2003, 8:21:33 AM5/21/03
Search for "Object Store, functionality" in your eVC online help. You don't
get a full description of the organisation of the database but at least a
brief description. Also, from there you will find links to the different
API's, datastructures etc.


Maarten Struys
PTS Software bv
"ragi" <> wrote in message

Susan Loh [MS]

May 22, 2003, 2:14:43 PM5/22/03
Take a look at this article and those listed below it, they should help:

I've already suggested we reproduce them in the eVC documentation (right now
they're only in Platform Builder) and add more overview material.

Sue (remove "online" from reply-to address)
This posting is provided "AS IS" with no warranties, and confers no rights.
Windows Embedded FAQ

"Maarten Struys" <> wrote in message

Maarten Struys

May 22, 2003, 5:26:00 PM5/22/03
It would definitely be great to have that stuff in the eVC documentation.


Maarten Struys
PTS Software bv

"Susan Loh [MS]" <> wrote in message

Sid Price

May 22, 2003, 6:09:42 PM5/22/03

Having been struggling through the current docs (MSDN, PB, and eVC) it would
be great if the docs included an overview of a CEDB. There does not appear
to be a concept document, this is required since most of the terminology
used is quite different to other DB technologies. One example is the use of
the term "properties" rather than "fields".

As in most cases with CE it seems that what we have is good reference
material but very poor concept and foundation articles.


"Susan Loh [MS]" <> wrote in message

Susan Loh [MS]

May 27, 2003, 7:53:43 PM5/27/03
Here is a very informal, rough document which will hopefully get cleaned up
and added to our SDK soon. Unfortunately it does not paste well, sorry
about the table.

Databases were added early in CE's history as a lightweight way to store
ordered data in the object store. A database is a set of records and up to
four orderings (sort orders, also called indexes) on those records. Each
record is a set of one or more typed data values called properties. There
is no ordering on the properties.

So, for example, a customer database could store a record for each
customer, with a property containing the customer's last name, another
property for their first name, and perhaps more properties for the
customer's account number, balance, etc. Perhaps there would be one sort
order on names and another on account numbers. That would make it possible
to list the customers in alphabetical order, or to search for a particular
customer by name or by account number.

There can be up to four sort orderings on the records, where each ordering
is on up to three properties. If an ordering is defined on three
properties, what that means is that there's one primary property by which
all records are ordered, but if two records have the same value for that
property, then we use the secondary property to order them further, and if
the second properties match we go to the tertiary property as a
tie-breaker. For example, if your customer database has one sort on last
name, then first name, then middle name, then the last name will be used
to order them. If any customers have matching last names, then their first
names will be used. If any customers have matching last and first names,
then their middle names will be used to determine their order. Finally, if
all three names match, then the ordering of the records is random. This is
not the same as three separate orderings on one property each; if your
customer database has one ordering on last names, a second ordering on
first names, and a third ordering on middle names, then what you'd have is
three completely independent orderings. If you were using the sort order
on last names, then all customers would be in order of last name, but if
their last names matched, they'd be in random order with respect to each
other. The database would not fall back to the first name to determine an

Sort orders are important for more than just iterating through all of the
records in order. In order to search for a record which contains a
particular property value, such as to search for a customer by name, your
database must have a sort order on that value. If you have no sort order
on last names, you cannot search for a customer who has a particular last
name. If the sort order is defined for multiple properties, you can search
using some or all of those properties. With the previous example of a
database sorted on last name, then first name, then middle name, you could
search for a customer solely by last name, or by the combination of last
and first names, or by all three names. You could not use the sort order
to search for a customer solely by first name, or solely by middle name, or
a combination of the two. Nor could you search for a customer by last and
middle name without using the first name. So the sort orders on a database
must be chosen with care to provide the kinds of data lookup that will be
required. It is possible to change the sort orders that are defined for a
database, but that can be a very expensive operation because it requires
re-sorting all of the records.

Sometimes I use the terms "sort order" and "sort index" rather
interchangeably; but when I'm being more formal, the difference to me is
that a "sort order" is the description of the sort while the "sort index"
is the implementation of it.

In the original implementation of databases for CE, there was only one
volume available for storing databases in: the object store, also called
the system volume or system heap. This volume not only holds databases, but
also holds the contents of the registry and file system. In CE 2.12, the
database API was extended so that separate volumes can be created, to store
databases in separate files or on different media such as storage cards.
One volume can hold any number of databases and database records.

You will find that the resulting API set has different terminology from
other database engines such as SQL. A "database" in CEDB is known as a
"table" in other database engines. A "volume" in CEDB is called a
"database" elsewhere, which can be very confusing. A "record" in CEDB is a
"row" elsewhere, a "property" in CEDB is a "field" elsewhere. So be
careful of terminology.

Another very different detail about CEDB is that it does not require a
clearly defined schema like other database engines do. My definition may be
wrong, but to me a schema is a model for what the records in the database
should look like and the relationships between them. CEDB has no relational
information, and it allows records to contain as many or as few properties
as desired. Some records can have more or fewer properties than others, and
some records may contain different property types than others. Simply
writing a new record or writing a new property to an existing record can
change the set of property types in the database. You can also delete a
property from an existing record without replacing it. This is rather
unusual for a database implementation; most require the set of property
types to be the same for all records and don't allow that set to be changed
once it is defined.

Since any record can contain any set of property types, it must be possible
to indicate which type each property has. So each property type has a
PropID which is a unique identifier for the type of property it is. The
PropID is a 32-bit value which is a combination of a 16-bit CEVT_* type
identifier with a 16-bit user-defined value, the purpose of which is to
make the PropID unique. All properties inside a record have different
PropIDs, but two records could contain properties with matching PropIDs. In
our example of a customer database, there would be one PropID for all "last
name" properties, another for all "first name" properties, and so on. Two
different records which represent two different customers would each
contain a last name, but no customer record would contain two last names.
So if two different records contain the same PropID that simply means that
both records contain that type of value.

Do not allow yourself to be confused by the distinction between PropIDs and
property values, or propvals. A PropID says what type of property a
particular value is, and a propval is the actual value. So for a
particular customer, for their last name "property," the PropID is the
"last name" PropID which is common among all records in the database, while
the propval is the actual value of the customer's last name, such as

Sometimes you might have a need to refer to a specific record within a
database. For this purpose, every record in a database is given a unique
identifier, an OID (object ID). You can search for the record using its
OID. In fact, searches by OID are very fast because they do not require a
search through the sort order. The OID is the FSHANDLE of the record
header in the heap, plus a 4-bit counter. The counter is used to make OIDs
as unique as possible; if a record was deleted, another record could be
created using the same FSHANDLE. But when a record is allocated, the
counter for its OID is incremented, so that the two records have different
OIDs. The older record might have OID 0x30000240, while the newer record
would have OID 0x31000240. Since the counter is 4-bit, the record would
have to be deleted 16 times before its OID would repeat. This makes it
less likely that applications would have problems with stale OIDs that they
incorrectly use after the records they refer to are deleted.

The following table contains a quick overview of the APIs available in
CEDB. The first version of APIs (v.1, CE 2.11 and earlier) worked only in
the object store and did not include any volume support. The second version
(v.2, CE 2.12 and 3.0) included volumes. The third revision of the APIs
(v.3, CE 4.0 and later) was necessary to support multiple-property sort

Volume APIs
Create a new database volume or mount an existing one. Databases inside
the volume will not be accessible unless it is currently mounted by at
least one thread.
v.1: -
v.2: CeMountDBVol
v.3: CeMountDBVol

Unmount a volume. The volume is reference counted and will not really
disappear until all threads that mounted it have unmounted it.
v.1: -
v.2: CeUnmountDBVol
v.3: CeUnmountDBVol

Flush any changes in the volume to its backing file. The volume is flushed
in the background at undefined times, so the only way to ensure that data
has been written to disk is to explicitly flush it.
v.1: -
v.2: CeFlushDBVol
v.3: CeFlushDBVol

Change the locale ID for a database volume.
v.1: -
v.2: CeChangeDatabaseLCID
v.3: CeChangeDatabaseLCID

Enumerate through the list of mounted database volumes.
v.1: -
v.2: CeEnumDBVolumes
v.3: CeEnumDBVolumes

Identifier-Based APIs:
Create a new database inside a mounted volume.
v.1: CeCreateDatabase
v.2: CeCreateDatabaseEx
v.3: CeCreateDatabaseEx2

Open a handle to an existing database.
v.1: CeOpenDatabase
v.2: CeOpenDatabaseEx
v.3: CeOpenDatabaseEx2

Change one or more settings for an existing database.
v.1: CeSetDatabaseInfo
v.2: CeSetDatabaseInfoEx
v.3: CeSetDatabaseInfoEx2

Delete a database.
v.1: CeDeleteDatabase
v.2: CeDeleteDatabaseEx
v.3: CeDeleteDatabaseEx

Query information about an existing OID.
v.1: CeOidGetInfo
v.2: CeOidGetInfoEx
v.3: CeOidGetInfoEx2

Look for a database in a particular volume, or in the overall "cloud" of
mounted volumes.
v.1: CeFindFirstDatabase / CeFindNextDatabase
v.2: CeFindFirstDatabaseEx / CeFindNextDatabaseEx
v.3: CeFindFirstDatabaseEx / CeFindNextDatabaseEx

Handle-Based APIs:
Seek to a particular position in the database, or find a record with the
desired set of property values. An open database handle keeps a pointer to
its current position inside the database, and CeSeekDatabase moves the
pointer to a new position.
v.1: CeSeekDatabase
v.2: CeSeekDatabase
v.3: CeSeekDatabaseEx

Create a new record and write properties to it, or add/overwrite/delete
properties in an existing record. Move the current position to that record.
v.1: CeWriteRecordProps
v.2: CeWriteRecordProps
v.3: CeWriteRecordProps

Read a set of desired properties from the current record. Auto-increment
the current position if necessary.
v.1: CeReadRecordPropsEx
v.2: CeReadRecordPropsEx
v.3: CeReadRecordPropsEx

Delete a record.
v.1: CeDeleteRecord
v.2: CeDeleteRecord
v.3: CeDeleteRecord

Query information about the database that a handle is open on.
v.1: -
v.2: -
v.3: CeGetDBInformationByHandle

A database has a maximum of 64k-1 records, 65535. While application writers
sometimes want to exceed this limit, a CEDB database tends to have real
performance problems with that much data. You should really be using a
beefier database engine when you have record counts in the tens of

A database volume has a maximum size of 16MB. Again, performance reasons
make it necessary to limit size. There is no maximum on the number of
databases. The maximum size in bytes of a single database would be (max #
records) * (max record size) but it is not an important number.

As noted above, CEDB is recommended only for customers who need
light-weight databases for a relatively small amount of data. The shell
uses databases for the positions of the desktop icons, and for tracking the
contents of the recycle bin. The notification system uses databases to
store notifications. The POOM apps use them to hold contacts, appointments,
and lists of email (usually the content of the email is stored separately
to escape the record size limit).

Sue (remove "online" from reply-to address)
This posting is provided "AS IS" with no warranties, and confers no rights.
Windows Embedded FAQ

| From: "Sid Price" <>
| References: <080a01c31eaa$40f2e680$a501...@phx.gbl>
| Subject: Re: CEDB
| Date: Thu, 22 May 2003 16:09:42 -0600
| Lines: 61
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <eoMle7KI...@TK2MSFTNGP11.phx.gbl>
| Newsgroups:
| NNTP-Posting-Host:
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP11.phx.gbl
| Xref: cpmsftngxa06.phx.gbl
| X-Tomcat-NG:

Sid Price

May 28, 2003, 11:28:45 AM5/28/03
Thanks so much Susan, just exactly what is required. I figured most of this
out using the current documents but I really appreciate the effort you made
in putting this together. CE needs more of these "background" and "overview"
types of documents.

Again, many thanks,

""Susan Loh [MS]"" <> wrote in message



May 29, 2003, 9:47:22 AM5/29/03
Thanks a lot Susan.
I am really very grateful to you.

But, I have another issue. I have heard of these set of
APIs called addrstor that are useful to store contacts and
sync them with MS Outlook.

Can u update me on this...

Thanks and Warm Regards

Susan Loh [MS]

May 29, 2003, 8:58:06 PM5/29/03
I'm sorry, I don't know anything about those APIs. You might want to start
a new thread with that as the subject, in hopes that other people who know
more will be able to help you.


Sue (remove "online" from reply-to address)
This posting is provided "AS IS" with no warranties, and confers no rights.
Windows Embedded FAQ

| Content-Class: urn:content-classes:message
| From: "ragi" <>
| Sender: "ragi" <>
| References: <080a01c31eaa$40f2e680$a501...@phx.gbl>
| Subject: Re: CEDB - a new problem
| Date: Thu, 29 May 2003 06:47:22 -0700
| Lines: 11
| Message-ID: <4c0e01c325e8$d480b130$a001...@phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain;
| charset="iso-8859-1"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: Microsoft CDO for Windows 2000
| X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4910.0300
| Thread-Index: AcMl6NSAsxYX2mRITFKvi9CTcGDdug==
| Newsgroups:
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl
| NNTP-Posting-Host: TK2MSFTNGXA08
| X-Tomcat-NG:

0 new messages