COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	Copyright (c) Geoworks 1994, 1995 -- All Rights Reserved
			GEOWORKS CONFIDENTIAL

FILE:	datastor.def


REVISION HISTORY:
	
	Name	Date		Description
	----	----		-----------
	cassie	10/3/95		Initial revision

DESCRIPTION:
	Contains description of the DataStore database engine
		
	$Id: datastor.def,v 1.1 97/04/04 14:26:56 newdeal Exp $

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@

SetDef	__DATASTORE

include	file.def			; for FileDateAndTime
include datax.def

StartLibrary	datastor

;------------------------------------------------------------------------
;  			Constants
;------------------------------------------------------------------------

RecordID	type	dword		
RecordNum	type	RecordID
FieldID		type	byte

MAX_FIELD_ID	= 	0xfe	; fields are numbered from 0-255
NULL_FIELD	= 	0xff

MAX_FIELD_NAME_LENGTH	= 40

	
;------------------------------------------------------------------------
;  			Structures
;------------------------------------------------------------------------

;
; Flags used in DataStoreOpen and DataStoreCreate
;
DataStoreOpenFlags	record
	DSOF_EXCLUSIVE:1	; Open the file with exclusive access - 
				; noone else may open it while it is
				; opened exclusive
	:7
DataStoreOpenFlags	end

DataStoreFlags	record
	DSF_PRIVATE:1		; may be opened by owner only
	DSF_TIMESTAMP:1		; first field contains record timestamp
	DSF_BACKUP:1		; is a backup file	UNSUPPORTED
	DSF_ARCHIVE:1		; is an archive copy	UNSUPPORTED
	DSF_RECORD_ID:1		; INTERNAL USE ONLY
	DSF_NO_PRIMARY_KEY:1	; this DataStore has no primary key fields
	DSF_TRACK_MODS:1	; enables deletion tracking and
				; modification numbers
	:9
DataStoreFlags	end

DataStoreFieldType 		etype byte, 0
	DSFT_FLOAT	enum DataStoreFieldType	; FloatNum
	DSFT_SHORT	enum DataStoreFieldType	; word
	DSFT_LONG	enum DataStoreFieldType	; dword
	DSFT_TIMESTAMP	enum DataStoreFieldType	; FileDateAndTime
	DSFT_DATE	enum DataStoreFieldType	; DataStoreDate
	DSFT_TIME	enum DataStoreFieldType	; DataStoreTime
	DSFT_STRING	enum DataStoreFieldType	; array of TCHAR, *not*
						;   null-terminated
	DSFT_BINARY	enum DataStoreFieldType	; array of bytes
	DSFT_GRAPHIC	enum DataStoreFieldType	; graphics image as an array
						;   of bytes
	DSFT_INK	enum DataStoreFieldType	; ink image as an array 
						;   of bytes

FieldCategory 		etype byte, 0
	FC_NONE			enum FieldCategory
	FC_NAME			enum FieldCategory
	FC_DATE			enum FieldCategory
	FC_TELEPHONE		enum FieldCategory
	FC_ADDRESS		enum FieldCategory
	FC_EMAIL		enum FieldCategory

FieldFlags	record
	FF_PRIMARY_KEY:1	; This field is part of primary key (INTERNAL)
	FF_DESCENDING:1		; If a key field, sort in descending order.
				;   Default is ascending order.
	FF_TIMESTAMP:1		; This field is the timestamp field (INTERNAL)
	:5
FieldFlags	end

;
;  Structures used to set and get data for Date and Time fields
;
DataStoreTime	struct 
    DST_hour		byte
    DST_minute		byte
    DST_second		byte
DataStoreTime	ends 

DataStoreDate 	struct
    DSD_year		word
    DSD_month		byte
    DSD_day		byte
DataStoreDate	ends

;
; Structures used to define fields and get field info
;
FieldData			struct
	FD_type		DataStoreFieldType
	FD_category	FieldCategory
	FD_flags	FieldFlags
FieldData			ends

FieldDescriptor			struct
	FD_data		FieldData
	FD_name		fptr.TCHAR
FieldDescriptor			ends

SortOrder		etype byte, 0
	SO_ASCENDING		enum SortOrder
	SO_DESCENDING		enum SortOrder

;-----------------------------------------------------------------------
;	RecordHeader and FieldHeader
;-----------------------------------------------------------------------

FieldHeader	struct
	FH_id		FieldID		; field name token
	FH_size		word		; # bytes in the field, counting
					;   the FieldHeader 
	FH_data		label	byte
FieldHeader	ends

FieldHeaderFixed	struct
	FHF_id		FieldID		; field name token
	FHF_data	label	byte
FieldHeaderFixed	ends

RecordHeader	struct
	RH_id		RecordID
	; The unique ID of this record

	RH_size		word
	; Size of record, including header

	RH_fieldCount	byte
	; The number of fields in this record

	RH_fieldData	label	FieldHeader
RecordHeader	ends


;------------------------------------------------------------------------
;  			Index Array Block
;------------------------------------------------------------------------
; Format of an IndexArray block. There is an array of 
; record numbers (low word only) that starts at the offest specified in
; IABH_array. Application-specific data may be stored at IABH_extraData.
; The size of the extra data area is specified when the index is
; created. 

IndexArrayBlockHeader 	struct
    IABH_recCount	word	    ; count of records in array
    IABH_array		word	    ; offset to array
    IABH_indexField	FieldID	    ; field to index on
    IABH_sortOrder	SortOrder   ; order field was sorted in
    IABH_extraData	label byte  ; app-defined extra data
IndexArrayBlockHeader 	ends


;-----------------------------------------------------------------------
;	DataStore Change Notification structures
;-----------------------------------------------------------------------
;
; When opening or creating a datastore, an app can add an object to the
; GAGCNLT_DATASTORE_CHANGE list, in which case it will receive
; notifications of type GWNT_DATASTORE_CHANGE with a block containing
; a DataStoreChangeNotification structure.
;

DataStoreChangeType	etype	word
	DSCT_RECORD_ADDED		enum	DataStoreChangeType
	; Indicates that a record was added to the datastore

	DSCT_RECORD_CHANGED		enum	DataStoreChangeType
	; Indicates that a record changed

	DSCT_RECORD_DELETED		enum	DataStoreChangeType
	; Indicates that a record was deleted

	DSCT_FIELD_ADDED		enum	DataStoreChangeType
	; Indicates that a field was added to the datastore

	DSCT_FIELD_RENAMED		enum	DataStoreChangeType
	; Indicates that a field was renamed

	DSCT_FIELD_DELETED		enum	DataStoreChangeType
	; Indicates that a field was deleted

	DSCT_DATASTORE_CHANGED		enum 	DataStoreChangeType
	; Indicates that there were large-scale changes to the 
	; datastore (e.g. it is newly created, was deleted or restored
	; from backup).

	DSCT_NAME_CHANGED		enum 	DataStoreChangeType
	; Indicates the datastore was renamed

	DSCT_NEXT_RECORD_ID_CHANGED	enum 	DataStoreChangeType
	; Indicates the record id that will be assigned to the next
     	; new record is changed. ( changed explicitly, instead of 
     	; through creating a new record.)


DataStoreChangeNotification	struct
;
;	This is the notification sent out when a datastore is modified.
;
	DSCN_name		TCHAR (FILE_LONGNAME_BUFFER_SIZE) dup (?)
	; The name of the datastore that has been changed

	DSCN_action		DataStoreChangeType
	; Indicates the type of modification that just occurred

;	The following fields are only filled in if DSCN_action is
;	DSCT_RECORD_DELETED, DSCT_RECORD_CHANGED, or DSCT_RECORD_ADDED

	DSCN_record		RecordID
	; The record that was just added/modified/deleted

;	The following field is only filled in if DSCN_action is
;	DSCT_FIELD_ADDED or DSCT_FIELD_DELETED

	DSCN_field		FieldID
	; The field that was just added/deleted

DataStoreChangeNotification	ends


;-----------------------------------------------------------------------
;	Error Codes
;-----------------------------------------------------------------------

DataStoreError 		etype word, 0

DSE_NO_ERROR					enum DataStoreError
DSE_INVALID_TOKEN				enum DataStoreError
DSE_DATASTORE_LOCKED				enum DataStoreError
DSE_ACCESS_DENIED				enum DataStoreError
DSE_WRITE_ERROR					enum DataStoreError
DSE_MEMORY_FULL					enum DataStoreError
DSE_INVALID_RECORD_ID				enum DataStoreError
DSE_INVALID_NAME				enum DataStoreError
DSE_INVALID_KEY_LIST				enum DataStoreError
DSE_INVALID_FLAGS				enum DataStoreError
DSE_DUPLICATE_FIELD_NAME			enum DataStoreError
DSE_CREATE_ERROR				enum DataStoreError
DSE_OPEN_ERROR					enum DataStoreError
DSE_CLOSE_ERROR					enum DataStoreError
DSE_UPDATE_ERROR				enum DataStoreError
DSE_DATASTORE_EXISTS				enum DataStoreError
DSE_DATASTORE_NOT_FOUND				enum DataStoreError
DSE_DATASTORE_ALREADY_OPEN			enum DataStoreError
DSE_PROTOCOL_ERROR				enum DataStoreError
DSE_CLOSE_WITH_LOCKED_RECORD			enum DataStoreError
DSE_INVALID_DATASTORE_FILE			enum DataStoreError
DSE_PRIVATE_DATASTORE				enum DataStoreError
DSE_BAD_SEARCH_PARAMS				enum DataStoreError
DSE_CANNOT_SET_NEXT_RECORD_ID_SMALLER		enum DataStoreError
DSE_NO_MATCH_FOUND				enum DataStoreError
DSE_NO_MORE_RECORDS				enum DataStoreError

DataStoreStructureError 	etype word, 0

DSSE_NO_ERROR					enum DataStoreStructureError
DSSE_INVALID_TOKEN				enum DataStoreStructureError
DSSE_DATASTORE_LOCKED				enum DataStoreStructureError
DSSE_ACCESS_DENIED				enum DataStoreStructureError
DSSE_WRITE_ERROR				enum DataStoreStructureError
DSSE_MEMORY_FULL				enum DataStoreStructureError
DSSE_TOO_MANY_FIELDS				enum DataStoreStructureError
DSSE_INVALID_FIELD_ID				enum DataStoreStructureError
DSSE_INVALID_FIELD_NAME				enum DataStoreStructureError
DSSE_INVALID_FIELD_TYPE				enum DataStoreStructureError
DSSE_INVALID_FIELD_CATEGORY			enum DataStoreStructureError
DSSE_INVALID_FIELD_FLAGS			enum DataStoreStructureError
DSSE_RECORD_BUFFER_NOT_EMPTY			enum DataStoreStructureError
DSSE_FIELD_NAME_TOO_LONG			enum DataStoreStructureError
DSSE_FIELD_NAME_EXISTS				enum DataStoreStructureError
DSSE_FIELD_NOT_FOUND				enum DataStoreStructureError
DSSE_TIME_STAMP_CANNOT_BE_ADDED			enum DataStoreStructureError
DSSE_TIME_STAMP_CANNOT_BE_DELETED		enum DataStoreStructureError
DSSE_INVALID_SORT_ORDER				enum DataStoreStructureError
DSSE_NO_RECORDS_IN_DATASTORE			enum DataStoreStructureError
DSSE_PARTIAL_INDEX_RETURNED			enum DataStoreStructureError
DSSE_DELETE_PRIMARY_KEY				enum DataStoreStructureError
DSSE_INDEX_RECORD_NUMBER_LIMIT_EXCEEDED		enum DataStoreStructureError        
.assert ( DSSE_NO_ERROR eq DSE_NO_ERROR )
.assert ( DSSE_INVALID_TOKEN eq DSE_INVALID_TOKEN )
.assert ( DSSE_ACCESS_DENIED eq DSE_ACCESS_DENIED )
.assert ( DSSE_DATASTORE_LOCKED eq DSE_DATASTORE_LOCKED )
.assert ( DSSE_WRITE_ERROR eq DSE_WRITE_ERROR )
.assert ( DSSE_MEMORY_FULL eq DSE_MEMORY_FULL )


DataStoreDataError 	etype word, 0

DSDE_NO_ERROR					enum DataStoreDataError
DSDE_INVALID_TOKEN				enum DataStoreDataError
DSDE_DATASTORE_LOCKED				enum DataStoreDataError
DSDE_ACCESS_DENIED				enum DataStoreDataError
DSDE_WRITE_ERROR				enum DataStoreDataError
DSDE_MEMORY_FULL				enum DataStoreDataError
DSDE_INVALID_RECORD_ID				enum DataStoreDataError
DSDE_INVALID_FIELD_ID				enum DataStoreDataError
DSDE_INVALID_FIELD_NAME				enum DataStoreDataError
DSDE_INVALID_FIELD_TYPE				enum DataStoreDataError
DSDE_INVALID_FIELD_CATEGORY			enum DataStoreDataError
DSDE_INVALID_FIELD_FLAGS			enum DataStoreDataError
DSDE_RECORD_BUFFER_NOT_EMPTY			enum DataStoreDataError
DSDE_RECORD_BUFFER_EMPTY			enum DataStoreDataError
DSDE_INVALID_FIELD_DATA				enum DataStoreDataError
DSDE_DATASTORE_READ_ONLY			enum DataStoreDataError
DSDE_INVALID_RECORD_NUMBER			enum DataStoreDataError
DSDE_INVALID_DATA_SIZE				enum DataStoreDataError
DSDE_FIELD_DOES_NOT_EXIST			enum DataStoreDataError
DSDE_RECORD_READ_ONLY				enum DataStoreDataError
DSDE_RECORD_NOT_FOUND				enum DataStoreDataError
DSDE_READ_ERROR					enum DataStoreDataError
DSDE_EXCEEDS_BUFFER_SIZE			enum DataStoreDataError
DSDE_TOO_MANY_FIELDS				enum DataStoreDataError
DSDE_RECORD_IN_USE				enum DataStoreDataError
DSDE_INVALID_BLOCK_HANDLE			enum DataStoreDataError
DSDE_INVALID_CHUNK_HANDLE			enum DataStoreDataError
DSDE_RECORD_LOCKED				enum DataStoreDataError


.assert ( DSDE_NO_ERROR eq DSE_NO_ERROR )
.assert ( DSDE_INVALID_TOKEN eq DSE_INVALID_TOKEN )
.assert ( DSDE_DATASTORE_LOCKED eq DSE_DATASTORE_LOCKED )
.assert ( DSDE_WRITE_ERROR eq DSE_WRITE_ERROR )
.assert ( DSDE_MEMORY_FULL eq DSE_MEMORY_FULL )
.assert ( DSDE_INVALID_RECORD_ID eq DSE_INVALID_RECORD_ID)
.assert ( DSDE_INVALID_FIELD_ID eq DSSE_INVALID_FIELD_ID)
.assert ( DSDE_INVALID_FIELD_NAME eq DSSE_INVALID_FIELD_NAME)
.assert ( DSDE_INVALID_FIELD_TYPE eq DSSE_INVALID_FIELD_TYPE)
.assert ( DSDE_INVALID_FIELD_CATEGORY eq DSSE_INVALID_FIELD_CATEGORY)
.assert ( DSDE_INVALID_FIELD_FLAGS eq DSSE_INVALID_FIELD_FLAGS)
.assert ( DSDE_RECORD_BUFFER_NOT_EMPTY eq DSSE_RECORD_BUFFER_NOT_EMPTY)

;-----------------------------------------------------------------------
;	Routine Definitions
;-----------------------------------------------------------------------

global	DataStoreCreate:far
;
; Creates a DataStore file.
;
; Pass:		ds:si - DataStoreCreateParams
; Return:	if carry set,
;			ax = DataStoreError
;		else 	ax = datastore token
;

DataStoreCreateParams	struct
	DSCP_name	fptr.char	; name of datastore
	DSCP_flags	DataStoreFlags	; only DSF_PRIVATE, DSF_TIMESTAMP,
					;   & DSF_NO_PRIMARY_KEY may be passed
	DSCP_keyList	fptr		; ptr to list of fields in primary key
	DSCP_keyCount	word		; number of entries in keyList. if 0,
					;   must pass DSF_NO_PRIMARY_KEY in
					;   DSCP_flags
	DSCP_notifObject optr		; object to notify if datastore changes
	DSCP_openFlags	DataStoreOpenFlags
DataStoreCreateParams	ends


global	DataStoreOpen:far
;
;  Opens the named DataStore. If object is non-NULL, GWNT_DATASTORE_CHANGE 
;  notifications will be sent to that object whenever the datastore
;  changes. If the flag DSOF_EXCLUSIVE is passed, the app will open the file
;  with exclusive access if no other application has the datastore open.
;  if the file is opened by anyone else, this call will fail with 
;  DSE_ACCESS_DENIED. 
;  Returns a datastore token in location pointed to by dsToken.
;
; Pass:		es:di - name
;		cx:dx - optr object to notify of datastore changes
;		al - open flag
;
; Return:	if carry set, 
;			ax = DataStoreError
;		else
;			ax = datastore token
;

global	DataStoreClose:far
;
; Closes the DataStore associated with the token.
;
; Pass: 	ax - DataStore token
; Return: 	ax - DataStoreError
;		carry set if error
;

global	DataStoreDelete:far
;
; Deletes a DataStore file, if it is not in use
;
; Pass: 	ds:dx - name
; Return: 	ax - DataStoreError
;		carry set if error
;

global	DataStoreRename:far
;
; Renames a DataStore file
;
; Pass: 	ds:dx - old name
; 	 	es:di - new name
; Return: 	ax - DataStoreError
;		carry set if error
;

global DataStoreGetFlags:far
;
; Returns the number of records in the datastore
; Pass:           ax - datastore token
;
; Return:         carry set if error,
;                     	ax - DataStoreError
;		  else
;			ax - DataStoreFlags
;

global	DataStoreGetFieldCount:far
;
; Gets the number of fields defined in this datastore
;
; Pass:		ax - DataStore token
;
; Return:	if carry set,
;			ax - DataStoreError
;		else
;			ax - field count
;

global	DataStoreGetRecordCount:far
;
; Gets the number of records in this datastore
;
; Pass:		ax - DataStore token
;
; Return:	if carry set,
;			ax - DataStoreError
;		else
;			dx.ax - record count
;

global	DataStoreGetOwner:far
;
; Gets the GeodeToken of the datastore's creator.
;
; Pass:		ax - datastore token
;		es:di - buffer to hold GeodeToken
;
; Return:	if carry set,
;			ax - DataStoreError
;

global	DataStoreGetVersion:far
;
; Gets the version of the datastore.
;
; Pass:		ax - datastore token
;
; Return:	if carry set,
;			ax - DataStoreError
;		else
;			cx - PN_major
;			dx - PN_minor
;

global	DataStoreSetVersion:far
;
; Sets the datastore's version.
;
; Pass:		ax - datastore token
;		cx - PN_major
;		dx - PN_minor
;
; Return:	if carry set,
;			ax - DataStoreError
;

global	DataStoreGetExtraData:far
;
; Gets extra data from the datastore into the passed buffer, copying
; no more than the cx bytes. Actual number of bytes copied is returned
; in cx.
;
; Pass:		ax - datastore token
;		cx - size of buffer
;		es:di - data buffer
;
; Return:	if carry set,
;			ax - DataStoreError
;		cx - number of bytes copied
;

global	DataStoreSetExtraData:far
;
; Store extra data in the datastore. Pass cx = 0 to delete any existing
; extra data.
;
; Pass:		ax - datastore token
;		cx - number of bytes of extra data
;		ds:dx - data buffer
;
; Return:	ax - DataStoreError
;

global	DataStoreGetTimeStamp:far
;
; Gets date and time of last modification to the datastore.
;
; Pass:		ax - datastore token
;
; Return:	ax - DataStoreError
;		cx - FileDate
;		dx - FileTime 
;

global	DataStoreSetTimeStamp:far
;
; Sets datastore timestamp
;
; Pass:		ax - datastore token
;		cx - FileDate
;		dx - FileTime 
; Return:	ax - DataStoreError
;

global	DataStoreGetNextRecordID:far
;
; Gets the RecordID that will be assigned to the next new record
;
; Pass:		ax - datastore token
; Return:	carry set if error,
;			ax - DataStoreError
;		else  dx.ax - RecordID
;

global	DataStoreSetNextRecordID:far
;
; Sets the RecordID that will be assigned to the next new record
;
; Pass:		ax - datastore token
;		dx.cx - next RecordID
; Return:	ax - DataStoreError
;

global	DataStoreAddField:far
;
; Adds a field to the DataStore schema
;
; Pass:		ax - DataStore token
;		es:di - FieldDescriptor
;
; Return:	if carry set,
;			ax - DataStoreStructureError
;		else
;			al - FieldID
;

global	DataStoreDeleteField:far
;
; Removes a field from the DataStore schema and from every record in the
; DataStore which has it
;
; Pass:		ax - DataStore token
;		cx:si - field name
;		dl - FieldID
;
; Return:	ax - DataStoreDataError
;

global	DataStoreRenameField:far
;
; Changes the name of a field of the given data store
;
; Pass:		ax - DataStore token
;		es:di - new field name
;		bx:si - old field name, pass bx = 0 to only use field id.
;		dl - FieldID, field id is ignored if bx is non-zero.
; Return:	ax - DataStoreStructureError
;

global  DataStoreFieldNameToID:far
;
; Gets ID of a field with a given name
;
; Pass:		ax - DataStore token
;		es:di - field name
; Return:	if carry set 
;			ax - DataStoreStructureError
;		else
;			al - FieldID
;

global  DataStoreFieldIDToName:far
;
; Gets the name of a field with a given ID
;
; Pass:		ax - DataStore token
;		dl - FieldID	
;		cx - size of name buffer
;		es:di - name buffer 
; Return:	if carry set:
;			ax - DataStoreStructureError
;			
;		else:	
;			cx - # of bytes copied
;			(es:di - field name)
;

global  DataStoreGetFieldInfo:far
;
; Gets the information of a field with a given ID
;
; Pass:		ax - DataStore token
;		dl - FieldID	
;		es:di - FieldDescriptor buffer
;		cx - size of buffer (in bytes) pointed to by descriptor's
;		     FD_name.  Set to 0 if name is not desired.
;
; Return:	carry set if error
;		ax - DataStoreStructureError
;

global	DataStoreNewRecord:far
;
; Creates a record with no fields, and stores the information in a memory block
;
; Pass: 	ax - datastore token
; Return: 	if carry set, 
;			ax - DataStoreDataError
;

global	DataStoreLoadRecord:far
;
; Loads the passed record into the buffer and makes it the current record
;
; Pass: 	ax - datastore token
;		dx.cx - RecordID of record to load
;
; Return: 	if carry set,
;			ax - DataStoreDataError
;		else
;			dx.cx - RecordNum of this record
;

global	DataStoreLoadRecordNum:far
;
; Like DataStoreLoadRecord, but uses RecordNum instead of RecordID.
;
; Pass: 	ax - datastore token
;		dx.cx - record number of record to lock
;
; Return: 	if carry set,
;			ax - DataStoreDataError
;		else
;			dx.cx - RecordID of the given record
;

global	DataStoreDiscardRecord:far
;
; Flushes the record from the buffer without saving any changes
;
; Pass: 	ax - datastore token
;
; Return: 	ax - DataStoreDataError
;

global	DataStoreSaveRecord:far
;
; Saves any changes made to the current record to datastore file and
; flushes the record from buffer
;
; Pass: 	ax - datastore token
;		bp - extra data (stack frame)
;		cx:dx - callback to do comparison
;		    Callback is passed:
;			es:di - ptr to record being inserted (record 1)
;			ds:si - ptr to record in datastore (record 2)
;			ax - datastore token
;			bp - extra data
;		    Return:
;			ax = -1,  if record 1 comes before record 2 
;			ax = 0,  if record 1 is equal to record 2
;			ax = 1,  if record 1 comes after record 2
; Return:	if carry set:
;		    ax - DataStoreDataError
;		else
;		    dx.ax - record number of saved record
;		    bx.cx - record ID of saved record
;

global	DataStoreSaveRecordNoUpdate:far
;
; Same as above, but doesn't update the timestamp.
;

global	DataStoreLockRecord:far
;
; Locks the current record
;
; Pass: 	ax - datastore token
;
; Return: 	if carry set
;			ax - DataStoreDataError
;		else
;			ds:si - ptr to the current record (RecordHeader)
;

global	DataStoreUnlockRecord:far
;
; Unlocks the current record
;
; Pass: 	ax - datastore token
;
; Return: 	nothing
;

global	DataStoreGetFieldPtr:far
;
; Returns a pointer to a given field
;
; Pass: 	ax - datastore token
; 		ds:si - RecordHeader
;		dl - FieldID
;
; Return: 	if carry set, ax - DataStoreDataError
;		else:
;		  cx - field size
;		  dh - field type
;		  ds:di - ptr to field content
;

global	DataStoreDeleteRecord:far
;
; Deletes a record from the database
;
; Pass: 	ax - datastore token
;		dx.cx - RecordID
; Return:	ax - DataStoreDataError
;

global	DataStoreDeleteRecordNum:far
;
; Deletes a record with given record number from the database
;
; Pass: 	ax - datastore token
;		dx.cx - record number
; Return:	ax - DataStoreDataError
;

global	DataStoreGetRecordID:far
;
; Gets the id of the current record
;
; Pass: 	ax - datastore token
;
; Return: 	if carry set,
;			ax - DataStoreDataError
;		else
;			dx.ax - RecordID
;

global	DataStoreSetRecordID:far
;
; If the new id is the same as the id stored in the datastore buffer,
; then do nothing. Otherwise, change the RecordID for the current
; record to the value passed if the datastore is opened for exclusive
; access.  The record must be saved for the change to be permanent. If
; there already exists a record with this RecordID, it will be overwritten.
; If the RecordID is greater than the next RecordID to be assigned to
; a new record, the next RecordID will be updated to the passed
; RecordID plus one. Record ID can be from the FIRST_RECORD_ID(inclusize)
; to LAST_RECORD_ID (exclusize);
; 
; Pass: 	ax - datastore token
;		dx.cx - RecordID
;
; Return: 	ax - DataStoreDataError
;

global	DataStoreSetRecordID:far
;
; Sets the id of the current record
;
; Pass: 	ax - datastore token
;		dx.cx - RecordID
;
; Return: 	ax - DataStoreDataError
;

global	DataStoreGetFieldSize:far
;
; Gets the size of a field
;
; Pass: 	ax - datastore token
;		bx:si - field name
;		dl - FieldID
;
; Return: 	if carry set,
;			ax - DataStoreDataError
;		else
;			ax - size of the field, 0 if field is not found.
;

global	DataStoreGetField:far
;
; Gets the data from a field
;
; Pass: 	ax - datastore token
;		bx:si - field name
;		dl - FieldID
;		es:di - destination for field data
;		cx - max # bytes to copy, if 0, then allocate a new block
;
; Return: 	if carry set,
;			ax - DataStoreDataError
;		else
;			bx - handle of block containing the field's
;			     data, if cx was passed 0
;			cx - # bytes of data copied, 0 if field is not found.


global	DataStoreGetFieldChunk:far
;
; Gets the data from a field into a chunk
;
; Pass: 	ax - datastore token
;		cx:si - field name. If cx = 0, FieldID is used
;		dl - FieldID, ignored if cx != 0
;		bx - MemHandle of block to put data in
;		di - ChunkHandle, or 0 to allocate a new one
;
; Return: 	if carry set,
;			ax - DataStoreDataError
;		else
;			ax - ChunkHandle of chunk containing the
;			field's data
;			cx - # bytes of data copied, 0 if field is not present
			
global	DataStoreSetField:far
;
; Sets the data for the field
;
; Pass:		ax - datastore token
;		bs:si - field name. If bx = 0, FieldID is used.
;		dl - FieldID, ignored if bx != 0
;		es:di - new field data
;		cx - size of field data
;
; Return: 	ax - DataStoreDataError
;

global	DataStoreRemoveFieldFromRecord:far
;
; Removes a field from the current record
;
; Pass: 	ax - datastore token
;		cx:si - field name
;		dl - FieldID
; Return:	ax - DataStoreDataError 
;

global	DataStoreMapRecordNumToID:far
;
; Gets the RecordID of the passed record number
;
; Pass: 	ax - datastore token
;		dx.cx - record number
;
; Return: 	dx.cx - RecordID
;

global	DataStoreGetNumFields:far
;
; Gets the number of fields present in the current record
;
; Pass: 	ax - datastore token
;
; Return: 	if carry set:
;			ax - DataStoreDataError
;		else
;			ax - number of fields	
;

global	DataStoreStringSearch:far
;
; Performance a search on a given datastore
;
; Pass: 	ax - datastore token
;		es:di - SearchParams
;
; Return: 	if carry set:
;			ax - DataStoreError
;		else
;			dx.ax - record number of the matching record
;			bl - fieldID of matching field
;

global DataStoreGetCurrentTransactionNumber:far
;
; Return the current transaction number
; Pass:		ax - datastore token
; Return:	if carry set:
;			ax - DataStoreError
; 		else
;			dx.cx - transaction number
;

SearchType		etype byte, 1
	ST_ALL			enum SearchType
	ST_FIELD		enum SearchType
	ST_CATEGORY		enum SearchType

SearchFlags	record
	SF_BACKWARDS:1
	SF_START_AT_END:1
	SF_IGNORE_CASE:1	
	SF_NO_WILDCARDS:1
	SF_PARTIAL_WORD:1
	:3
SearchFlags	end

SearchParams		struct
	SP_searchType		SearchType
	SP_startRecord		RecordNum
	SP_maxRecords		dword
	SP_startField		FieldID
	SP_category		FieldCategory
	SP_searchString		fptr
	SP_flags		SearchFlags
SearchParams		ends


global	DataStoreBuildIndex:far
;
;  Creates an array of RecordNum (low word only), where records are sorted 
;  on the given field.  The array is stored in a block whose handle is
;  returned in indexHandle. The block has an IndexArrayBlockHeader,
;  followed by headerSize bytes of user data storage area, followed
;  by the index itself. If headerSize is less than the size of 
;  IndexArrayHeaderBlock, the standard header is used.
;
;  NOTE: The index contains only the low word of the record numbers, 
;  and may only be created on a DataStore which has 4000 records or less.
;
;  A callback can be used to modify the index order. It is called
;  for each pair of records which are compared while building the index.
;  If a callback is passed, DSICP_indexField and DSICP_sortOrder are 
;  ignored.
;
; Pass: 	ax - datastore token
;		ds:si - array of DataStoreIndexCallbackParams
;			bx ==  null to create new block
;		dx - size of IndexArray header,
;			0 to use default size (IndexArrayBlockHeader)
;		bp - callback data (on stack)
;		cx:di - callback routine to do comparison
;		    Callback is passed:
;			ax - datastore token
;			ds:si - fptr to DataStoreIndexCallbackParams
;			bp - callback data
;		    Return:
;			ax = -1,  if record 1 comes before record 2 
;			ax =  1,  if record 1 comes after record 2
; Return:	if carry set:
;		    ax - DataStoreStructureError
;		else
;		        ^hbx - IndexArray block
;

DataStoreIndexCallbackParams	struct
	DSICP_indexField	FieldID
	DSICP_sortOrder		SortOrder
	DSICP_cbData		fptr
	DSICP_rec1		fptr.RecordHeader
	DSICP_rec2		fptr.RecordHeader
DataStoreIndexCallbackParams	ends


global	DataStoreRecordEnum:far
;
; Enumerates all the records in storage order
;
; Pass: 	ax - datastore token
;		si - DataStoreRecordEnumFlags
;		dx.cx - record number to start at
;		bx.di - vfptr of callback routine
;		bp - callback data
;		    Callback is passed:
;			ds:di - RecordHeader
;			bp - callback data
;		    Return:
;			carry set to stop enum
; Return:	if carry clear,
;		    if ax = DSE_NO_ERROR, callback was aborted, and
;		       dx.cx = index of last record examined
;		    if ax = DSE_NO_MORE_RECORDS, last record was reached
;		       dx.cx = index of record following last record examined
;		else carry set 
;			ax - DataStoreError
;

DataStoreRecordEnumFlags	record
    DSREF_BACKWARDS:1		; records should be enumerated in reverse order
    DSREF_START_AT_END:1	; if set, will ignore passed record number and
				;   will start at first or last record,
				;   depending on DSREF_BACKWARDS flag
    :13
    DSREF_RESERVED:1		; this bit is reserved for internal use only
DataStoreRecordEnumFlags	end


global	DataStoreFieldEnum:far
;
; Enumerates all fields in the current record
;
; Pass: 	ax - datastore token
;		ds:si - RecordHeader
;		bx:di - vfptr to callback
;		    Callback is passed:
;			ds:di - ptr to field content
;			cx - field content size
;			al - field type
;			ah - field category
;			dl - field id
;			dh - field flags
;			bp - callback data
;		    Return:
;			value to pass in bp on next callback
;			carry set to stop enum
;		    Can destroy:	ax, cx, dx, di
; Return:	carry - set if error
;

;
; C declarations
;

global  DATASTORECREATE:far
global  DATASTOREOPEN:far
global  DATASTORECLOSE:far
global  DATASTOREDELETE:far
global  DATASTORERENAME:far
global  DATASTOREGETFIELDCOUNT:far
global  DATASTOREGETRECORDCOUNT:far
global  DATASTOREGETFLAGS:far
global  DATASTOREGETOWNER:far
global  DATASTOREGETVERSION:far
global  DATASTORESETVERSION:far
global  DATASTOREGETEXTRADATA:far
global  DATASTORESETEXTRADATA:far
global  DATASTOREGETTIMESTAMP:far
global  DATASTORESETTIMESTAMP:far
global  DATASTOREGETNEXTRECORDID:far
global  DATASTORESETNEXTRECORDID:far
global  DATASTOREADDFIELD:far
global	DATASTOREDELETEFIELD:far
global	DATASTORERENAMEFIELD:far
global	DATASTOREFIELDNAMETOID:far
global	DATASTOREFIELDIDTONAME:far
global 	DATASTOREGETFIELDINFO:far
global	DATASTORENEWRECORD:far
global  DATASTORELOADRECORD:far
global  DATASTORELOADRECORDNUM:far
global  DATASTOREDISCARDRECORD:far
global  DATASTORESAVERECORD:far
global  DATASTORESAVERECORDNOUPDATE:far
global  DATASTORELOCKRECORD:far
global  DATASTOREUNLOCKRECORD:far
global  DATASTOREGETFIELDPTR:far
global	DATASTOREDELETERECORD:far
global	DATASTOREDELETERECORDNUM:far
global	DATASTOREGETRECORDID:far
global	DATASTORESETRECORDID:far
global  DATASTOREGETFIELDSIZE:far
global  DATASTOREGETFIELD:far
global  DATASTOREGETFIELDCHUNK:far
global  DATASTORESETFIELD:far
global	DATASTOREREMOVEFIELDFROMRECORD:far
global	DATASTOREMAPRECORDNUMTOID:far
global	DATASTORESETRECORDID:far
global	DATASTOREGETNUMFIELDS:far
global	DATASTORESTRINGSEARCH:far
global  DATASTOREBUILDINDEX:far
global  DATASTORERECORDENUM:far
global  DATASTOREFIELDENUM:far
global	DATASTOREGETCURRENTTRANSACTIONNUMBER:far

DSApplicationClass class DataXApplicationClass
DSApplicationClass endc


EndLibrary	datastor
