/* Basic manipulations */

/* open the database. */
/* the db url is of the form
 * "file://usr/local/acedb/worm" indicating that the desired database 
 * is local, or of the form "acedb://moot.cadif.cornell.edu:211014" 
 * indicating that the desired  database is remote, and should be 
 * accessed over the network protocol.  The nature of that protocol 
 * will remain transparent to the user of the library, and the 
 * functionality of the API is not altered in any way.
 */
/* Ace structures represent the context information required to   
 * distinguish between multiple connections in the same program.
 * It is possible that there may be a restriction to only a single 
 * local open database in a given address space.  There will be no 
 * restriction on the number of remote databases which may be open 
 * at one time.  Likewise, there may be simultaneously open a single 
 * local database and one or more remote databases. 
 */
/* in the few places where an instancename is required, it should be a 
 * qualified name, in the format " classname : name ".  The exact 
 * lexical analysis of this string is to be determined.
 */
/* many of the routines utilize the ACeDB memory management concept of
 * an AceHandle, which allows the garbage collection of all memory allocated
 * utilizing that handle when the handle itself is destroyed.
 * While the Ace* context will create a handle, it is quite possible that
 * certain applications may wish to exert additional control over the 
 * management of these handles.  As a result, any routine which returns
 * structures that the user of the library must destroy allows an AceHandle
 * to be passed to it.  That AceHandle will be used.  Pass an AceHandle of
 * 0 if you don't care.
 */
#define BLOCKING /* indicates routines which may block waiting */

typedef enum { _Int, _Text, _Float, _DateType, _Key, _Tag } AceType;
typedef Ace* void*;

extern int aceErrno;
char*  aceGetErrorBuffer(int* bufsize);
Bool   aceSetErrorBuffer(char* buffer);

Ace*  aceOpen(char* /* db url */);	
Bool  aceSetContext(Ace*);
Ace*  aceGetContext(void);

/* get write lock */
/* will calls requesting write locks be allowed to block? */
Bool  aceAllowBlocking(Bool canBlock);/* -- unsupported, always fails */
BLOCKING Bool  aceWriteLock(void);

/* commit changes */
  /* -- unsupported, always fails */
Bool  aceCheckpoint(void);
/* check point a long transaction */
  /* -- unsupported, always fails */
Bool  aceRollback( Bool isAbort );
/* rollback.  If isAbort, rollback to start of transaction,
 * otherwise, rollback to last checkpoint.
 */
Bool	aceCommit( Bool releaseLock ); 

/* close the database. */
void  aceClose(Ace*, Bool autoCommit );

/* high-granularity operations */

/* list the ace classes */
AceStringSet aceClasses(AceHandle); 
int    aceClassSize(char* classname);

/* models */
AceInstance aceOpenModel(char* classname,AceHandle);
/* ask the database you are connected to to re-read its models */
BLOCKING Bool        aceReadModels(void);

/* features of instances */
char*    aceName(AceKey, AceHandle);
char*    aceClassName(AceKey, AceHandle);
char*    AceInstanceName(char* class, char* instance, AceHandle);
AceTag   AceTagOf(char* anyString, Bool create); 
AceKey   AceKeyOf(char* instancename, Bool create);
AceKey   AceKeyOfInstance(AceInstance);

/* instances */
AceKeyset       aceClassExtent(char* classname,AceHandle);
/* get a number of objects at once */
BLOCKING AceInstanceSet aceOpenAllInstancesNamed(char** names, 
						 Bool needWriteLock,AceHandle);
BLOCKING AceInstanceSet  aceOpenAllInstances(AceKeyset, 
					     Bool needWriteLock,AceHandle);
/* get a single object */
BLOCKING AceInstance  aceOpenInstanceNamed(char* instanceName,  
                                           Bool needWriteLock,AceHandle);
BLOCKING AceInstance  aceOpenInstance(AceKey,Bool needWriteLock,AceHandle);
/* finish with an object.  */
Bool                  aceCloseInstance(AceInstance, Bool commit);
Bool                  aceCloseAllInstances(AceInstanceSet, 
					   Bool commit);

/* grep.  Optionally, do LongGrep. */
AceKeyset       aceGrep(char* pattern, Bool doLong,AceHandle);
AceKeyset       aceGrepFrom(AceKeyset, char* pattern, Bool doLong,AceHandle);

/* filtering a set of keys/instances */
AceInstanceSet  aceFilterInstances(char* predicate, 
				   AceInstanceSet src,AceHandle);
AceKeyset       aceFilterKeys(AceKeyset src, char* predicate,AceHandle);

/* reading ace-format */
Bool aceParse(char*);
Bool aceParseFile(FILE*);

/* editing objects */
/* -- unsupported, always fails */
int aceEditInstances(AceInstanceSet, char* command);
Bool aceEditAceKeyset(AceKeyset, char* command);

/* killing objects */
void aceKillName(char* instancename);
void aceKillKey(AceKey);
void aceKillAceKeyset(AceKeyset);

/* output */
/* %a = ace %h = human %j = java %p = perl, etc.
 * a '*' following the format specifier indicates that either an
 * entire AceKeyset or an entire AceInstanceSet should be dumped.
 * a 'i' following the format specifier indicates that we are working
 * with an INSTANCE (or AceInstanceSet) instead of a AceKey or AceKeyset.
 */
Bool acefprintf(FILE*,char* format, ...); 
Bool acesprintf(char*,char* format, size_t buflen);

/* new unique objects */
AceKey aceMakeKeyFromFormat(char* classname, char* format);

/* tree manipulation */
Bool    aceTestInstance(AceInstance, char* predicate, 
                        Bool moveCurrent);
/* mark/goto */
AceMark AceMark( AceInstance, AceHandle ); 
/* create the AceMark for the caller */
Bool    aceGotoMark( AceInstance, AceMark target );
/* search object */
Bool    aceGotoTag( AceInstance, AceKey target );
Bool    aceHasTag( AceInstance, AceKey target );
/* navigate object */
Bool    aceNextChild( AceInstance );
Bool    aceGotoChild( AceInstance );
/* verify the current type */
Bool    aceCheckType( AceInstance , AceType );
AceType aceGetType( AceInstance );
/* verify the presence of a type in the current follow set */
Bool    aceFollowedBy( AceInstance , AceType );

AceDateType aceGetDateType( AceInstance );
char*    aceGetText( AceInstance, AceHandle );
int      aceGetInteger( AceInstance );
float    aceGetFloat( AceInstance );
AceKey   aceGetKey( AceInstance );
AceTag   aceGetTag( AceInstance );

/* in place modifications of the object */
Bool     aceReplAceKey( AceInstance, AceKey );
Bool     aceReplAceTag( AceInstance, AceTag );
Bool     aceReplaceInteger( AceInstance, int );
Bool     aceReplaceText( AceInstance, char* );
Bool     aceReplaceFloat( AceInstance, float );
/* modify the position immediately to the right */
Bool     aceAddKey( AceInstance, AceKey );
Bool     aceAddTag( AceInstance, AceTag );
Bool     aceAddInteger( AceInstance, int );
Bool     aceAddText( AceInstance, char* );
Bool     aceAddFloat( AceInstance, float );
/* attach comments to the current position */
/* comments will no longer be inserted into the structure of the
 * object itself, but will be added along a third dimension.
 */
Bool     aceAddComment( AceInstance, char* );
char*    aceGetComment( AceInstance, AceHandle );
 
/* remove everything to the right of the current position,
 * as well as the current node.
 */
Bool     acePrune( AceInstance );

/* query interface */
/* there is a problem here, since the results is actually a table */
/* what is the structure of the data structure returned, and do we */
/* need to provide methods for accessing it? */
Bool     aceQuery(AceTable init, char* queryString, AceTable results);  
Bool     aceQueryInstance(AceInstance, char* queryString, AceInstance result);
AceTable aceMakeInstanceTable(AceInstance, int depth, AceHandle );
Bool     aceTableCell(AceTable table, int i, int j);
AceTable aceTableByName(char* tablename, AceHandle );

/* fancy ACeDB memory management stuff */
AceHandle aceHandleCreate(void);
Bool      aceHandleDestroy(void);
Bool      aceFree(void*);





