Listing 6

/* ----------------- PINLIST.H-------------------- */
#include "pinnacle.h"
#include "list.h"

#define PINNACLE_LIST_CLASS       LIST_CLASS \
/*  Pinnacle Database Object */       DB db; \
/*Pinnacle Database Table */    DBTAB table; \
/*  Boolean flags*/    unsigned is_at_top, is_at_bottom;

typedef struct pinnacle_list {
   PINNACLE_LIST_CLASS
} PINNACLE_LIST;

PINNACLE_LIST *new_pinnacle_list(char *database,
char *table);

/*------------------ PINLIST.C ------------------ */
#include "pinlist.h"

static long total_members(PINNACLE_LIST *this) {
   return((long) DB_CountRows(this->table));
}

static unsigned at_top(PINNACLE_LIST *this) {
   return(this->is_at_top);
}

static unsigned at_end(PINNACLE_LIST *this) {
   return(this->is_at_bottom);
}

static void prev(PINNACLE_LIST *this) {
   if (DB_NextRow(this->table, DBPREVIOUS))
      this->is_at_top = FALSE;
   else
      this->is_at_top = TRUE;
   if (this->total_members(this) > 1)
      this->is_at_bottom = FALSE;
}

static void next(PINNACLE_LIST *this) {
   if (DB_NextRow(this->table, DBNEXT))
      this->is_at_bottom = FALSE;
   if (this->total_members(this) > 1)
      this->is at bottom = TRUE;
      this->is_at_top = FALSE;
}

static void top(PINNACLE_LIST *this) {
   DB_FirstRow(this->table);
   DB_NextRow(this->table,DBNEXT);
   this->is_at_top = TRUE;
   if (this->total_members(this) > 1)
      this->is_at_bottom = FALSE;
}

static void end(PINNACLE_LIST *this) {
   DB_ForAllRows(this->table);
   this->is_at_bottom = TRUE;
   if (this->total_members(this) > 1)
   this->is_at_top = FALSE;
}

static long tell(PINNACLE_LIST *this) {
   DBROWID thisrow, checkrow;
   long position = 0L;
   
   thisrow = DB_CurrentRow(this->table);
   this->top(this);
   checkrow = DB_CurrentRow(this->table);
   while(checkrow != thisrow) {
      ++position;
      
      DB_NextRow(this->table,DBNEXT);
      checkrow = DB_CurrentRow(this->table);
   }
   return(position);
}

PINNACLE_LIST *new_pinnacle_list(char *datab,char *table) {
PINNACLE_LIST *this;
LIST *l;

l = new_list();
if (l == NULL)
   return(NULL);

this = calloc(1,sizeof(PINNACLE_LIST));
if (this == NULL) {
   destroy_list(l); return(NULL);
}
memmove(this,l,sizeof(LIST)); free(l);

this->db = DB_Open(datab,"rw",0);
this->table = DB_Table(this->db,table);
this->total_members = total_members;
this->at_top = at_top; this->at_end = at_end;
this->prev = prev; this->next = next;
this->top = top; this->end = end; this->tell = tell;

return(this);
}

destroy_pinnacle_list(PINNACLE_LIST *this) {
DB_Close(this->db); destroy_list(this);
}