Compass Server 3.0 Developer's Guide

[Contents] [Previous] [Next] [Last]

Chapter 13
Using the RDM API To Accesss the Compass Server Database in C

This chapter discusses the use of the Compass Server RDM API to access the Compass Server and its database using C. The RDM API provides routines to parse, modify, or create resource description messages (RDMs) using C.

The robot generates RDs and saves them to the Compass Server database. You can get the RDs in SOIF format, use the RDM API to modify them, then have Compass import them back.

The RDM API is defined in the rdm.h file in the following directory in your Compass Server installation directory:

bin/compass/sdk/rdm/include
This chapter does not teach you how to use C. This chapter is restricted to discussing the use of C functions that come with the Compass Server RDM API .

What is RDM?

Resource Description Messages (RDM) is a messaging format which two processes can use to exchange resource descriptions across a network. In RDM, one process (a client or agent) sends a request RDM message to another process (a server) which processes the request, then sends a response RDM message, similiar to the HTTP/1.0 request/response model.

For more information about RDM, see:

http://www.w3.org/TR/NOTE-rdm.html

For example, you can send an RDM to a Compass Server database to request RDs that match a certain criteria (or scope). The Compass Server will send back a response RDM that contains the requested RDs (such as all the documents containing the string "style sheets.")

RDM Format Syntax

Each RDM message contains a header and a body. The header identifies the nature of the RDM message, while the body contains the data required to carry out the needed request (for example, scoping critiera). Both the header and body of the RDM message is encoded using SOIF. (Chapter 11, Using the SOIF API to Work with SOIF Objects gives more information about SOIF format.)

RDM Header

The RDM header section begins with a SOIF object whose schema-name is RDMHEADER which must contain as least the following attributes:

The following RDM header attribute is optional:

Some example RDM headers include:

@RDMHEADER { -
  rdm-version{3}: 1.0
  rdm-type{14}: status-request
}
@RDMHEADER { -
  rdm-version{3}: 1.0
  rdm-type{9}: RDM_RD_REQ
  rdm-query-language{8}: compass
  catalog-service-ID{39}: x-catalog://nikki.boots.com:80/techpubs
}

RDM Body

The RDM message body contains the data needed to carry out the request. For example, if the header is RDM_RD_REQ, which indicates a query request, the body must contain the query criteria, or the scope. For example, if you are sending a request to find all documents that contain the string "netscape," then the body must be SOIF object whose schema-name is RDMQuery and whose Scope attribute is netscape:

@RDMQUERY { -
  scope{3}:netscape
}
If the RDM is a query request, the body of the message can also indicate which attributes of the resulting RDS are wanted, how many results you want, and how you want them sorted. For example, the following RDM body specifies that we're interested in the URL, title, author, and last-modified attributes. The result set contains at most 10 hits and the result set is ordered by the title attribute:

@RDMQUERY { -
  scope{3}:netscape
  view-attributes{x}: url,title,author,last-modified
  view-hits{x}: 10
  view-order{x}: title
}
If the RDM message is some other kind of request, such as a Schema-Description-Request or a Server-description-request or a Status request, the body of the message must contain appropriate data. See the following document for more details of RDM bodies:

http://www.w3.org/TR/NOTE-rdm.html

About the RDM API

The file rdm.h defines structures and functions for creating RDMs. The intent of these functions is to construct queries and instructions in C, which can be output as RDM and sent via the sendrdm program to a Compass Server for processing .

The basic structures are:

To support each of these main structures, there are additional structures, for example RDMViewAttributes, RDMViewOrder, RDMViewHit, which would each be used to represent attributes in an RDMQuery.

The RDM API defined in rdm.h provides functions for creating and modifying these structures. For example, the following statement:

RDMQuery *myquery = RDMQuery_Create("netscape");
creates an RDMQuery that corresonds to the following SOIF:

@RDMQUERY { -
  scope{3}:netscape
}
The following statement:

RDMQuery_SetViewAttr(myquery, "URL,Title");
modifies the RDMQuery so that it corresponds to the following SOIF:

@RDMQUERY { -
  scope{3}:netscape
view-attributes{x}: URL,Title,Author,Last-Modified
}
Both the RDMHeader and RDMQuery structures have soif fields, which contain the SOIF data for the header or the query. To get the SOIF data out of the RDMHeader or RDMQuery, you can access the soif field.

OK, so you can use the RDM API to create and modify RDMHeader and RDMQuery objects. But at some point you'll want to send them to the Compass Server to actually perform a query request. How do you do that?

The answer is that you can use the pre-built sendrm program, which you can find in the compassdir/bin/compass/bin directory. This program takes an RDM request (which is a message in SOIF format), sends it to the Compass Server, and outputs the results as a SOIF stream.

Example of Submitting a Query

Here is a sample program that generates an RDM for querying a Compass Server database. (You can get the source code as a separate file in example4.c.)

You must pipe the output to a temporary file then use the sendrdm program to post it to the Compass Server.The sendrdm program is at compassdir/bin/compass/bin/sendrdm.

You must change the definitions for MY_CSID, MY_SCOPE and MY_ATTR_VIEW in the code to suit your needs.

MY_CSID is the id of your Compass Server instance. This is the specific Compass Server that you created in the Compass Server Administration Interface. You can find the exact value in compassServerDir/config/csid.conf.

MY_SCOPE is the query string to search for. The default is to search for documents containing the string "netscape". For example, if you want to search for all documents containing the string "style sheets", then set MY_SCOPE to "style sheets."

MY_ATTR_VIEW is the attributes to be printed out, such as URL, title and description.

/******* Example Use of the RDM API to submit a query *******/
#include <stdio.h>
#include "soif.h"
#include "rdm.h"
#define MY_SCOPE "netscape"
#define MY_CSID    "x-catalog://nikki.boots.com:6714/compass1"
#define MY_ATTR_VIEW "title,content-type"
int main(int argc, char *argv)
{
  RDMQuery *myquery = NULL;
  CSID *csid = NULL;
  RDMHeader *myheader = NULL;
  SOIFStream *out = SOIF_PrintInitFile(stdout);
  /* Create the RDMQuery and specify its scope */
  if(!(myquery = RDMQuery_Create(MY_SCOPE))) {
    perror("RDMQuery_Create\n");
    exit(-1);
  }
  /* Set the view attributes of the RDMQuery */
  RDMQuery_SetViewAttr(myquery, MY_ATTR_VIEW);
  /* Create the CSID that points to your Compass Server instance */
  if(!(csid = CSID_Parse(MY_CSID))) {
    perror("CSID_Parse\n");
    exit(-1);
  }
  /* Create the RDMHeader */
  if(!(myheader = RDMHeader_CreateRequest(RDM_RD_REQ, "compass", csid)))   {
    perror("RDMHeader_CreateRequest\n");
    exit(-1);
  }
  /* print the RDMHeader to the output SOIF stream */
  /* print the RDMQuery to the output SOIF stream */
  (*out->print)(out, myheader->soif);
  (*out->print)(out, myquery->soif);
  /* free the structures and exit */
  RDMHeader_Free(myheader);
  RDMQuery_Free(myquery);
  SOIFStream_Finish(out);
  exit(0);
}
/*********** EOF ****************/

Running the Example

You can find the complete source code in example4.c.

1.) Edit the definitions for MY_SCOPE, MY_CSID, and MY_ATTR_VIEW as appropriate for your situation.

2.) Save the file in compassdir/bin/compass/sdk/rdm/examples.

3.) Create a makefile. You can find sample makefiles at compassdir/bin/compass/sdk/rdm/examples. Edit the makefiles to include example4. The following code shows the makefile with the changes needed for example4 in bold:

#  Makefile for SOIF/RDM SDK examples 
#  Use make and cc. 
CC              = cc 
SDKDIR          = .. 
SDKLIB          = $(SDKDIR)/lib/librdm.a 
SDKINC          = $(SDKDIR)/include/ 
CFLAGS          = -I$(SDKINC) -DXP_UNIX 
CFLAGS          += -DSOLARIS 
#CFLAGS         += -DHPUX 
#CFLAGS         += -DAIX 
#CFLAGS         += -DIRIX 
EXAMPLES        = example1 example2 example3 example4 
all:    $(EXAMPLES) 
example1:       example1.o 
        $(CC) -o $@ $@.o $(SDKLIB) 
example2:       example2.o 
        $(CC) -o $@ $@.o $(SDKLIB) 
example3:       example3.o 
        $(CC) -o $@ $@.o $(SDKLIB) 
example4:       example4.o 
        $(CC) -o $@ $@.o $(SDKLIB) 
4.). From the directory compassdir/bin/compass/sdk/rdm/examples, build the example as follows.:

Solaris:    gmake 
NT: nmake -f makefile.win 
5.). From the directory compassdir/bin/compass/sdk/rdm/examples, run the example4 program to generate the RDM file.

example4 > rdm.soif
The file rdm.soif will look something like:

RDMHEADER { - 
  catalog-service-id{41}: x-catalog://newport.mcom.com:6714/newport
  rdm-version{3}: 1.0
  rdm-type{10}: rd-request
  rdm-query-language{7}: compass
} 
@RDMQUERY { - 
  view-attributes{18}: title,content-type
  scope{8}: netscape
}
6.). Send the SOIF contained in rdm.soif to the program sendrdm.

../../../bin/sendrdm  rdm.soif 
The results of the sendrdm program will be a SOIF stream containing the results of the query, such as:

@RDMHEADER { - 
  catalog-service-id{41}: x
  catalog://newport.mcom.com:6714/newport
  rdm-version{3}: 1.0
  rdm-type{11}: rd-response
  rdm-response-interpret{51}:20 results out of 36281 hits across 88985 documents
}
@DOCUMENT {
  http://fury.netscape.com:999/it/newsref/pr/newsrelease417.html
  content-type{9}: text/html
  score{3}: 100
  title{17}: Comunicato stampa
}
@DOCUMENT {
  http://fury.netscape.com:999/it/newsref/pr/newsrelease374.html
  content-type{9}: text/html
  score{3}: 100
  title{17}: Comunicato stampa
}
You can pipe the output of sendrdm (which is a SOIFStream) to another program to print the results of the query, or do whatever else with the results that you want.

See the section An Introductory Example in Chapter 11, Using the SOIF API to Work with SOIF Objects for an example of how to print information about SOIFs contained in a SOIF stream.

API Reference

The rest of this chapter discusses the RDM API, which you can find in compassdir/bin/compass/sdk/rdm/include/rdm.h.

Finding the RDM Version


RDM_Version

NSAPI_PUBLIC const char *RDM_Version(void);
Returns the version of the RDM library.

Creating and Freeing RDM Structures

For most RDMX structures, such as RDMRequest, RDMQuery, and so on, there are two or more creation functions. There is usually an RDMX_Parse() function, which takes SOIF arguments, and an RDMX_Create() function, which takes non-SOIF arguments.

There is also an RDMX_Free() function, which releases the object.

Several RDM structures also have an RDMX_merge() function, which merges data from a SOIF object into an existing RDMX structure.

RDMHeader

AN RDMHeader represents the header of an RDM. An RDMHeader structure has one public field, soif, which is a SOIF containing a collection of attribute-value pairs. The allowable attribute names of the attribute-value pairs in the SOIF are:

Response RDMs also have several attributes, and you can find them in rdm.h if you are interested.

The following statements create an RDMHeader whose RDMType is RDM_RD_REQ, and whose query language is "compass". This RDM will be sent to the Compass Server instance compass1 of the Compass Server at http://nikki.boots.com:6714.

CSID *csid = CSID_Parse("x-catalog://nikki.boots.com:6714/compass1");
RDMHeader *myheader = RDMHeader_CreateRequest(RDM_RD_REQ, "compass", csid);
The allowable values for RDM-Type are:

You can use the following macros to get and set the string values of the attributes:

RDMHeader_GetType(RDMHeader) /* returns RDMType */
RDMHeader_GetVersion(RDMHeader)
RDMHeader_GetQueryLanguage(RDMHeader)
RDMHeader_GetCSID(RDMHeader)
RDMHeader_GetResponseInterpret(RDMHeader)
RDMHeader_GetErrorMessage(RDMHeader)
RDMHeader_GetErrorNumber(RDMHeader)
RDMHeader_SetType(RDMHeader,RDMType) 
RDMHeader_SetVersion(RDMHeader,stringvalue)
RDMHeader_SetQueryLanguage(RDMHeader,stringvalue)
RDMHeader_SetCSID(RDMHeader,stringvalue)
RDMHeader_SetResponseInterpret(RDMHeader,stringvalue)
RDMHeader_SetErrorMessage(RDMHeader,stringvalue)
RDMHeader_SetErrorNumber(RDMHeader,stringvalue)

RDMHeader_Parse

NSAPI_PUBLIC RDMHeader *RDMHeader_Parse(SOIFStream *ss);

RDMHeader_Create

NSAPI_PUBLIC RDMHeader *RDMHeader_Create(RDMType t);

RDMHeader_CreateRequest

NSAPI_PUBLIC RDMHeader *RDMHeader_CreateRequest(RDMType, char *ql, 
CSID *)

RDMHeader_CreateResponse

NSAPI_PUBLIC RDMHeader *RDMHeader_CreateResponse(RDMType, char *ri,
CSID *);

RDMHeader_Free

NSAPI_PUBLIC int RDMHeader_Free(RDMHeader *r);

RDMHeader_Merge

NSAPI_PUBLIC int RDMHeader_Merge(RDMHeader *, SOIF *)
Merges data from a SOIF object into the RDMHeader object.

RDMQuery

AN RDMQuery represents the body of an RDM. An RDMQuery structure has one public field, soif, which is a SOIF containing a collection of attribute-value pairs. The allowable attribute names of the attribute-value pairs in the SOIF are:

You can use the following macros to get and set the string values of these attributes:

RDMQuery_GetScope(query)
RDMQuery_GetViewAttr(query)
RDMQuery_GetViewHits(query)
RDMQuery_GetViewOrder(query)
RDMQuery_GetViewTemplate(query)
RDMQuery_SetScope(query, value) 
RDMQuery_SetViewAttr(query,value-list)
RDMQuery_SetViewHits(query,value)
RDMQuery_SetViewOrder(query,value-list)
RDMQuery_SetViewTemplate(query,value)

RDMQuery_Parse

NSAPI_PUBLIC RDMQuery *RDMQuery_Parse(SOIFStream *ss);

RDMQuery_Create

NSAPI_PUBLIC RDMQuery *RDMQuery_Create(const char *scope);

RDMQuery_Free

NSAPI_PUBLIC int RDMQuery_Free(RDMQuery *);

RDMQuery_Merge

NSAPI_PUBLIC int RDMQuery_Merge(RDMQuery *, SOIF *);

Other RDM Structures

In addition to RDMHeader and RDMQuery, the file rdm.h provides definitions and functions for the following auxilliary objects. See the file rdm.h in compass/bin/sdk/rdm/include for details.


[Contents] [Previous] [Next] [Last]

Last Updated: 02/07/98 20:49:21

Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use