Пример #1
0
CONDITION
TBL_DeleteTable(TBL_HANDLE ** handle, const TBL_CRITERIA * criteriaList,
	const char* tableName)
{
  TBL_CONTEXT* tc;
  char* dbName;
  /*char *tableName;*/
  int foundit;
  char deleteCommand[2048];

  PGresult* res;
  PGconn* conn;

#ifdef CTN_USE_THREADS
    THR_ObtainMutex(FAC_TBL);
#endif

  tc = G_ContextHead;
  foundit = 0;
  while (tc != (TBL_CONTEXT *) NULL) {
    if (tc == (TBL_CONTEXT *) (*handle)) {
      dbName = tc->databaseName;
      /*tableName = tc->tableName;*/
      conn = (PGconn*)tc->dbSpecific;
      foundit = 1;
      break;
    }
    tc = tc->next;
  }
  if (!foundit) {
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_BADHANDLE), "TBL_Delete");
  }

  strcpy(deleteCommand, "DELETE FROM ");
  strcat(deleteCommand, tableName);

  if ((criteriaList != (TBL_CRITERIA *) NULL) && (criteriaList->FieldName != 0)) {
    strcat(deleteCommand, " WHERE ");
    addCriteria(criteriaList, deleteCommand);
  }
  strcat(deleteCommand, ";" );

  res = PQexec(conn, deleteCommand);
  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
    fprintf(stderr, PQresultErrorMessage(res));
    fprintf(stderr, "<%s>\n", deleteCommand);
    exit(1);
  }

  PQclear(res);

#ifdef CTN_USE_THREADS
  THR_ReleaseMutex(FAC_TBL);
#endif
  return TBL_NORMAL;
}
Пример #2
0
/* TBL_Close
**
** Purpose:
**	This function "closes" the specified table in the specified
**	database.
**
** Parameter Dictionary:
**	TBL_HANDLE **handle: The pointer for the database/table pair
**		to be closed.
**
** Return Values:
**	TBL_NORMAL: normal termination.
**	TBL_CLOSERROR: The handle to be closed could not be located
**		in the internal list or no database/table pairs
**		had been opened up to this point.
**
** Notes:
**	Nothing unusual.
**
** Algorithm:
**	Locates the handle specified in the call and removes that
**	entry from the internal list maintained by this	facility.
*/
CONDITION
TBL_Close(TBL_HANDLE ** handle)
{
    TBL_CONTEXT
    * prevtc,
    *tc,
    *hc;

#ifdef CTN_USE_THREADS
    THR_ObtainMutex();
#endif

    G_OpenFlag--;
    if (G_OpenFlag == 0) {
        mysql_close(&mysql);
    }
    hc = (TBL_CONTEXT *) (*handle);
    prevtc = tc = G_ContextHead;
    while (tc != (TBL_HANDLE *) NULL) {
        if (hc == tc) {
            tc->refCount--;
            if (tc->refCount > 0) {
#ifdef CTN_USE_THREADS
                THR_ReleaseMutex();
#endif
                return TBL_NORMAL;
            }
            free(tc->databaseName);
            free(tc->tableName);
            if (tc == G_ContextHead)
                G_ContextHead = tc->next;
            else
                prevtc->next = tc->next;
            free(tc);
            (*handle) = (TBL_HANDLE *) NULL;
#ifdef CTN_USE_THREADS
            THR_ReleaseMutex();
#endif
            return TBL_NORMAL;
        }
        prevtc = tc;
        tc = tc->next;
    }

#ifdef CTN_USE_THREADS
    THR_ReleaseMutex();
#endif
    return COND_PushCondition(TBL_ERROR(TBL_CLOSERROR), "TBL_Close");
}
Пример #3
0
CONDITION
COND_PopCondition(CTNBOOLEAN clearstack)
{
    CONDITION	value;

#ifdef CTN_USE_THREADS
    if (THR_ObtainMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_PopCondition unable to obtain mutex, exiting\n");
    	exit(1);
    }
#endif

    if (stackPtr >= 0){
    	value = EDBStack[stackPtr].statusCode;
    }else{
    	value = COND_NORMAL;
    }
    if (clearstack) {
    	stackPtr = -1;
    } else if (stackPtr <= 0) {
    	stackPtr = -1;
    } else {
    	stackPtr--;
    }

#ifdef CTN_USE_THREADS
    if (THR_ReleaseMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_PopCondition unable to release mutex, exiting\n");
    	exit(1);
    }
#endif

    return value;
}
Пример #4
0
void
COND_CopyText(char *txt, size_t length)
{
    size_t 		i;
    int 		j;

    txt[0] = '\0';

#ifdef CTN_USE_THREADS
    if (THR_ObtainMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_CopyText unable to obtain mutex\n");
    	return;
    }
#endif

    j = stackPtr;
    while (length > 2 && j >= 0) {
    	i = strlen(EDBStack[j].statusText);
    	if (i > length) i = length - 2;
    	strncpy(txt, EDBStack[j].statusText, i);
    	txt[i++] = '\n';
    	txt[i] = '\0';
    	length -= i;
    	txt += i;
    	j--;
    }

#ifdef CTN_USE_THREADS
    if (THR_ReleaseMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_CopyText unable to release mutex, exiting\n");
    	exit(1);
    }
#endif
}
Пример #5
0
CONDITION
COND_TopCondition(CONDITION * code, char *text, unsigned long maxlength)
{
    CONDITION rtnValue;
#ifdef CTN_USE_THREADS
    if (THR_ObtainMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_TopCondition unable to obtain mutex, exiting\n");
    	exit(1);
    }
#endif

    if (stackPtr >= 0) {
    	*code = EDBStack[stackPtr].statusCode;
    	(void) strncpy(text, EDBStack[stackPtr].statusText, maxlength - 1);
    	text[maxlength - 1] = '\0';
    	rtnValue = EDBStack[stackPtr].statusCode;
    } else {
    	*code = COND_NORMAL;
    	*text = '\0';
    	rtnValue = COND_NORMAL;
    }

#ifdef CTN_USE_THREADS
    if (THR_ReleaseMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_TopCondition unable to release mutex, exiting\n");
    	exit(1);
    }
#endif
    return rtnValue;
}
Пример #6
0
void
COND_WriteConditions(FILE * lfp)
{
#ifdef CTN_USE_THREADS
    if (THR_ObtainMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_WriteConditions unable to obtain mutex\n");
    	return;
    }
#endif
    dumpstack(lfp);
    stackPtr = -1;

#ifdef CTN_USE_THREADS
    if (THR_ReleaseMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_WriteConditions unable to release mutex\n");
    	return;
    }
#endif
}
Пример #7
0
/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      COND_PushCondition
**	This routine is used to log a condition on the stack.  The user
**	passes an error code (currently uninterpreted), a format string
**	and optional format arguments.  We use the vsprintf routine to
**	interpret the user's format string and arguments, and we place the
**	error condition and resultant string on the stack.
**
**  FORMAL PARAMETERS:
**
**      code:
**          The condition code of the error/warning.
**
**      controlString:
**          format string for vsprintf statement
**
**      [varargs]:
**          variable arguments to be used with controlString
**
**  RETURN VALUE:
**
**      code (as passed in by the user)
**
**  SIDE EFFECTS:
**
**      Places a new entry on the stack.  If the stack
**	fills up, drop the last condition.
**	Calls a user-established callback just before return.
**
*/
CONDITION
COND_PushCondition(CONDITION cond, char *controlString,...)
{
    va_list		args;
    char	    buffer[1024];

/*lint -e40 -e50 */
    va_start(args, controlString);
    if (controlString == NULL) controlString = "NULL Control string passedto PushCondition";
    (void) vsprintf(buffer, controlString, args);
    va_end(args);
/*lint +e40 +e50 */

#ifdef CTN_USE_THREADS
    if (THR_ObtainMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_PushCondition unable to obtain mutex\n");
    	return cond;
    }
#endif

    stackPtr++;
    EDBStack[stackPtr].statusCode = cond;
    buffer[256] = '\0';

    (void) strcpy(EDBStack[stackPtr].statusText, buffer);
    if (ErrorCallback != NULL) ErrorCallback(EDBStack[stackPtr].statusCode, EDBStack[stackPtr].statusText);

    if (stackPtr >= MAXEDB - 2) {
    	dumpstack(stderr);
    	fprintf(stderr, "CONDITION Stack overflow\n");
    	stackPtr = 0;
    }
#ifdef CTN_USE_THREADS
    if (THR_ReleaseMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_PushCondition unable to release mutex, exiting\n");
    	exit(1);
    }
#endif

    return cond;

}
Пример #8
0
CONDITION
COND_EstablishCallback(void (*callback) ())
{
#ifdef CTN_USE_THREADS
    if (THR_ObtainMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_EstablishCallback unable to obtain mutex, exiting\n");
    	exit(1);
    }
#endif

    ErrorCallback = callback;

#ifdef CTN_USE_THREADS
    if (THR_ReleaseMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_EstablishCallback unable to release mutex, exiting\n");
    	exit(1);
    }
#endif
    return COND_NORMAL;
}
Пример #9
0
unsigned short
SRV_MessageIDOut()
{
    static unsigned short	  messageID = 0;

#ifdef CTN_USE_THREADS
    if (THR_ObtainMutex(FAC_SRV) != THR_NORMAL) {
    	COND_DumpConditions();
    	fprintf(stderr, " SRV_MessageIDOut unable to obtain mutex, exiting\n");
    	exit(1);
    }
#endif
    messageID++;

#ifdef CTN_USE_THREADS
    if (THR_ReleaseMutex(FAC_SRV) != THR_NORMAL) {
    	COND_DumpConditions();
    	fprintf(stderr, " SRV_MessageIDOut unable to release mutex, exiting\n");
    	exit(1);
    }
#endif
    return messageID;
}
Пример #10
0
CONDITION
COND_ExtractConditions(CTNBOOLEAN(*callback) ())
{
    int        index, returnflag;

#ifdef CTN_USE_THREADS
    if (THR_ObtainMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_ExtractConditions unable to obtain mutex, exiting\n");
    	exit(1);
    }
#endif

    for (index = stackPtr, returnflag = 1; index >= 0 && returnflag != 0; index--) {
    	returnflag = callback(EDBStack[index].statusCode, EDBStack[index].statusText);
    }

#ifdef CTN_USE_THREADS
    if (THR_ReleaseMutex(FAC_COND) != THR_NORMAL) {
    	fprintf(stderr, "COND_ExtractConditions unable to release mutex, exiting\n");
    	exit(1);
    }
#endif
    return COND_NORMAL;
}
Пример #11
0
/* TBL_Update
**
** Purpose:
**	This updates existing records in the named table.
**
** Parameter Dictionary:
**	TBL_HANDLE **handle: The pointer for the database/table pair
**		to be accessed for modification.  This table must be open.
**	TBL_CRITERIA *criteriaList: Contains the list of criteria to
**		select those records that should be updated.
**	TBL_FIELD *fieldList: Contains a list of the keyword/value
**		pairs to be used to modify the selected records.
**
** Return Values:
**	TBL_NORMAL: normal termination.
**	TBL_BADHANDLE: The handle passed to the routine was invalid.
**	TBL_DBNOEXIST: The database specified does not exist.
**	TBL_NOFIELDLIST: No keyword/value pairs were specified for update.
**	TBL_UPDATEFAILED: The insert operation failed most probably from
**		a bad specification in the fieldList.  This error
**		return could result from a misspelled keyword, etc.
**
** Notes:
**	Nothing unusual.
**
** Algorithm:
**	The records which match the (ANDED) criteria in criteriaList
**	are retreived and updated with the information contained in
**	fieldList.  Only the fields contained in fieldList will be
**	updated by this call.
*/
CONDITION
TBL_Update(TBL_HANDLE ** handle, const TBL_CRITERIA * criteriaList,
	   TBL_UPDATE * updateList)
{
  TBL_CONTEXT* tc;
  TBL_FIELD* fp;
  char tabcol[100];
  char* dbName;
  char *tableName;
  int i;
  int ret;
  int FoundTextorBinary;
  int foundit;
  char updateCommand[2048];

  PGresult* res;
  PGconn* conn;
  int nTuples;

#ifdef CTN_USE_THREADS
    THR_ObtainMutex(FAC_TBL);
#endif

  tc = G_ContextHead;
  foundit = 0;
  while (tc != (TBL_CONTEXT *) NULL) {
    if (tc == (TBL_CONTEXT *) (*handle)) {
      dbName = tc->databaseName;
      tableName = tc->tableName;
      conn = (PGconn*)tc->dbSpecific;
      foundit = 1;
      break;
    }
    tc = tc->next;
  }
  if (!foundit) {
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_BADHANDLE), "TBL_Update");
  }

  strcpy(updateCommand, "UPDATE ");
  strcat(updateCommand, tableName);
  strcat(updateCommand, " SET ");
  addUpateValues(updateList, updateCommand);

  if ((criteriaList != (TBL_CRITERIA *) NULL) && (criteriaList->FieldName != 0)) {
    strcat(updateCommand, " WHERE ");
    addCriteria(criteriaList, updateCommand);
  }
  strcat(updateCommand, ";" );

  res = PQexec(conn, updateCommand);
  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
    fprintf(stderr, PQresultErrorMessage(res));
    fprintf(stderr, "<%s>\n", updateCommand);
    exit(1);
  }

  PQclear(res);

#ifdef CTN_USE_THREADS
  THR_ReleaseMutex(FAC_TBL);
#endif
  return TBL_NORMAL;
}
Пример #12
0
CONDITION
TBL_NextSequence(TBL_HANDLE ** handle, char *name, long *unique)
{
  TBL_CONTEXT* tc;
  TBL_FIELD* fp;
  char tabcol[100];
  char* dbName;
  char *tableName;
  int i;
  int ret;
  int FoundTextorBinary;
  int foundit;
  char selectCommand[2048];
  char updateCommand[2048];
  long realcount;
  long * lp;

  PGresult* res;
  PGconn* conn;
  int nTuples;

#ifdef CTN_USE_THREADS
    THR_ObtainMutex(FAC_TBL);
#endif

  tc = G_ContextHead;
  foundit = 0;
  while (tc != (TBL_CONTEXT *) NULL) {
    if (tc == (TBL_CONTEXT *) (*handle)) {
      dbName = tc->databaseName;
      tableName = tc->tableName;
      conn = (PGconn*)tc->dbSpecific;
      foundit = 1;
      break;
    }
    tc = tc->next;
  }
  if (!foundit) {
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_BADHANDLE), "TBL_NextSequence");
  }
  sprintf(selectCommand,
	  "SELECT nextval (\'%s\');",
	  name);
  res = PQexec(conn, selectCommand);
  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
    fprintf(stderr, PQresultErrorMessage(res));
    fprintf(stderr, selectCommand);
    exit(1);
  }

  *unique = -1;
  nTuples = PQntuples(res);
  if (nTuples != 1) {
    return COND_PushCondition(TBL_ERROR(TBL_BADHANDLE), "TBL_NextSequence: Expected 1 tuples in TBL_Next Serial, received %d", nTuples);
  }
  *unique=atoi(PQgetvalue(res, 0, 0));
  PQclear(res);

#ifdef CTN_USE_THREADS
  THR_ReleaseMutex(FAC_TBL);
#endif
  return TBL_NORMAL;
}
Пример #13
0
CONDITION
TBL_OpenDB(const char *databaseName, TBL_HANDLE ** handle)
{
  TBL_CONTEXT* tc;
  char *sn;
  char server_name[50];
  char *tdb;
  char *ttb;
  PGconn *conn;
  PGresult *res;
  char* tableName = "none";

  (*handle) = (void *) NULL;

#ifdef CTN_USE_THREADS
  THR_ObtainMutex(FAC_TBL);
#endif

  tc = G_ContextHead;
  while (tc != (TBL_CONTEXT *) NULL) {
    if ((strcmp(tc->databaseName, databaseName) == 0) &&
	(strcmp(tc->tableName, tableName) == 0)) {
      tc->refCount++;
      (*handle) = (void *) tc;
      G_OpenFlag++;
#ifdef CTN_USE_THREADS
      THR_ReleaseMutex(FAC_TBL);
#endif
      return TBL_NORMAL;
    }
    tc = tc->next;
  }
  conn = PQsetdb(NULL,		/* host */
		 NULL,		/* port */
		 NULL,		/* backend options */
		 NULL,		/* debugging tty for backend */
		 databaseName);
  if (PQstatus(conn) == CONNECTION_BAD) {
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_OPENFAILED), tableName);
  }

  /* We have to assume at this point that everything will be ok...
   */
  if ((tc = (TBL_CONTEXT *) malloc(sizeof(TBL_CONTEXT))) == (TBL_CONTEXT *) NULL) {
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_NOMEMORY), "TBL_Open");
  }
  if ((tdb = (char *) malloc(strlen(databaseName) + 1)) == (char *) NULL) {
    free(tc);
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_NOMEMORY), "TBL_Open");
  }
  if ((ttb = (char *) malloc(strlen(tableName) + 1)) == (char *) NULL) {
    free(tc);
    free(tdb);
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_NOMEMORY), "TBL_Open");
  }
  strcpy(tdb, databaseName);
  strcpy(ttb, tableName);
  tc->databaseName = tdb;
  tc->tableName = ttb;
  tc->refCount = 1;
  tc->dbSpecific = conn;
  tc->next = G_ContextHead;
  G_ContextHead = tc;

  (*handle) = (void *) G_ContextHead;

  G_OpenFlag++;

#ifdef CTN_USE_THREADS
  THR_ReleaseMutex(FAC_TBL);
#endif

  return TBL_NORMAL;

}
Пример #14
0
CONDITION
TBL_SelectTable(TBL_HANDLE ** handle, const TBL_CRITERIA * criteriaList,
     TBL_FIELD * fieldList, long *count, CONDITION(*callback) (), void *ctx,
     const char* tableName)
{
  TBL_CONTEXT* tc;
  TBL_FIELD* fp;
  char tabcol[100];
  char* dbName;
  int i;
  int ret;
  int FoundTextorBinary;
  int foundit;
  char selectCommand[2048];
  long realcount;
  long * lp;

  PGresult* res;
  PGconn* conn;
  int nTuples;

#ifdef CTN_USE_THREADS
    THR_ObtainMutex(FAC_TBL);
#endif

  tc = G_ContextHead;
  foundit = 0;
  while (tc != (TBL_CONTEXT *) NULL) {
    if (tc == (TBL_CONTEXT *) (*handle)) {
      dbName = tc->databaseName;
      /*tableName = tc->tableName;*/
      conn = (PGconn*)tc->dbSpecific;
      foundit = 1;
      break;
    }
    tc = tc->next;
  }
  if (!foundit) {
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_BADHANDLE), "TBL_Select");
  }

  strcpy(selectCommand, "SELECT ");
  addFieldNames(fieldList, selectCommand);
  strcat(selectCommand, " FROM " );
  strcat(selectCommand, tableName);

  if ((criteriaList != (TBL_CRITERIA *) NULL) && (criteriaList->FieldName != 0)) {
    strcat(selectCommand, " WHERE ");
    addCriteria(criteriaList, selectCommand);
  }
  strcat(selectCommand, ";" );

  if (count != (long *) NULL)
    lp = count;
  else
    lp = &realcount;
  *lp = 0;


  res = PQexec(conn, selectCommand);
  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
    fprintf(stderr, PQresultErrorMessage(res));
    fprintf(stderr, "<%s>\n", selectCommand);
    exit(1);
  }
  nTuples = PQntuples(res);

  for (i = 0; i < nTuples; i++) {
    (*lp)++;
    extractFieldResults(res, i, fieldList);

    if (callback != NULL) {
      if (callback(fieldList, *lp, ctx) != TBL_NORMAL) {
	PQclear(res);
#ifdef CTN_USE_THREADS
	THR_ReleaseMutex(FAC_TBL);
#endif
	return COND_PushCondition(TBL_ERROR(TBL_EARLYEXIT), "TBL_Select");
      }
    }
  }
  PQclear(res);

#ifdef CTN_USE_THREADS
  THR_ReleaseMutex(FAC_TBL);
#endif
  return TBL_NORMAL;
}
Пример #15
0
/* TBL_Select
**
** Purpose:
**	This function selects some number of records (possibly zero),
**	that match the criteria specifications given in the input
**	parameter criteriaList.
**
** Parameter Dictionary:
**	TBL_HANDLE **handle: The pointer for the database/table pair
**		to be accessed.  This table must be open.
**	TBL_CRITERIA *criteriaList: Contains a list of the criteria
**		to use when selecting records from the specified table.
**		A null list implies that all records will be selected.
**	TBL_FIELD *fieldList: Contains a list of the fields to be
**		retreived from each record that matches the criteria
**		specification.  It is an error to specify a null
**		fieldList.
**	int *count: Contains a number that represents the total number
**		of records retreived by this particular select.  If this
**		parameter is null, then an internal counter is used and
**		the final count will not be returned when the select
**		finishes.
**	CONDITION (*callback)(): The callback function invoked whenever
**		a new record is retreived from the database.  It is
**		invoked with parameters as described below.
**	void *ctx: Ancillary data passed through to the callback function
**		and untouched by this routine.
**
** Return Values:
**	TBL_NORMAL: normal termination.
**	TBL_BADHANDLE: The handle passed to the routine was invalid.
**	TBL_DBNOEXIST: The database specified does not exist.
**	TBL_NOFIELDLIST: A null field list pointer (fieldList *) was
**		specified.
**	TBL_SELECTFAILED: The select operation failed most probably from
**		a bad specification in the fieldList or criteriaList.  This
**		return is not the same as a valid query returning no records.
**		This error return could result from a misspelled keyword, etc.
**	TBL_EARLYEXIT: The callback routine returned something other than
**		TBL_NORMAL which caused this routine to cancel the remainder
**		of the database operation and return early.
**
** Algorithm:
**	As each record is retreived from the
**	database, the fields requested by the user (contained in
**	fieldList), are filled with the informatiton retreived from
**	the database and a pointer to the list is passed to the
**	callback routine designated by the input parameter callback.
**	The callback routine is invoked as follows:
**
**		callback(fieldList *fieldList, long count, void *ctx)
**
**	The count contains the number of records retreived to this point.
**	ctx contains any additional information the user originally passed
**	to this select function.  If callback returns any value other
**	than TBL_NORMAL, it is assumed that this function should terminate
**	(i.e. cancel the current db operation), and return an abnormal
**	termination message (TBL_EARLYEXIT) to the routine which
**	originally invoked the select.
*/
CONDITION
TBL_Select(TBL_HANDLE ** handle, const TBL_CRITERIA * criteriaList,
           TBL_FIELD * fieldList, long *count, CONDITION(*callback) (), void *ctx)
{
    TBL_CONTEXT
    * tc;
    TBL_FIELD
    * fp;
    TBL_CRITERIA
    * cp;
    char
    *dbName,
    *tableName;
    int
    i,
    foundit;
    long
    realcount,
    *lp;
    MYSQL_ROW
    row;
    MYSQL_RES
    * ans;

#ifdef CTN_USE_THREADS
    THR_ObtainMutex();
#endif

    tc = G_ContextHead;
    foundit = 0;
    while (tc != (TBL_CONTEXT *) NULL) {
        if (tc == (TBL_CONTEXT *) (*handle)) {
            dbName = tc->databaseName;
            tableName = tc->tableName;
            foundit = 1;
        }
        tc = tc->next;
    }
    if (!foundit) {
#ifdef CTN_USE_THREADS
        THR_ReleaseMutex();
#endif
        return COND_PushCondition(TBL_ERROR(TBL_BADHANDLE), "TBL_Select");
    }

    if (mysql_select_db(&mysql, dbName) != 0) {
#ifdef CTN_USE_THREADS
        THR_ReleaseMutex();
#endif
        (void) COND_PushCondition(TBL_ERROR(TBL_DBSPECIFIC), "mySQL",
                                  mysql_error(&mysql), "TBL_Select");
        return COND_PushCondition(TBL_ERROR(TBL_BADHANDLE), "TBL_Select");
    }

    /*
     * We found the names we need...just assume we can access it (for now).
     */
    if ((fieldList == (TBL_FIELD *) NULL) || (fieldList->FieldName == 0)) {
#ifdef CTN_USE_THREADS
        THR_ReleaseMutex();
#endif
        return COND_PushCondition(TBL_ERROR(TBL_NOFIELDLIST), "TBL_Select");
    }
    /*
     * Set up the select statement
     */
    mysqlcmd(&G_DBSelect, "SELECT ");
    fp = fieldList;
    Add_FieldName_to_Buf(G_DBSelect, fp);
    fp++;
    while (fp->FieldName != NULL) {
        mysqlcmd(&G_DBSelect, ",");
        Add_FieldName_to_Buf(G_DBSelect, fp);
        fp++;
    }
    mysqlcmd(&G_DBSelect, "FROM ");
    Add_String_to_Buf(G_DBSelect, tableName);
    cp = criteriaList;
    if ((cp != (TBL_CRITERIA *) NULL) && (cp->FieldName != 0)) {
        mysqlcmd(&G_DBSelect, " WHERE ");
        Add_Criteria_to_Buf(G_DBSelect, cp);
        cp++;
        while (cp->FieldName != NULL) {
            mysqlcmd(&G_DBSelect, " AND ");
            Add_Criteria_to_Buf(G_DBSelect, cp);
            cp++;
        }
    }
    if (count != (long *) NULL)
        lp = count;
    else
        lp = &realcount;
    *lp = 0;

    mysql_ping(&mysql);
    if (mysql_real_query(&mysql, G_DBSelect, (unsigned int)strlen(G_DBSelect)) != 0) {
        mysqlfreebuf(&G_DBSelect);
#ifdef CTN_USE_THREADS
        THR_ReleaseMutex();
#endif
        (void) COND_PushCondition(TBL_ERROR(TBL_DBSPECIFIC), "mySQL",
                                  mysql_error(&mysql), "TBL_Select");
        return COND_PushCondition(TBL_ERROR(TBL_SELECTFAILED), DATABASE, "TBL_Select");
    }
    ans = mysql_store_result(&mysql);
    while ((row = (MYSQL_ROW) mysql_fetch_row(ans)) != (MYSQL_ROW) NULL) {
        (*lp)++;
        for (fp = fieldList, i = 0; fp->FieldName != NULL; fp++, i++) {
            fp->Value.IsNull = 0;
            switch (fp->Value.Type) {
            case TBL_SIGNED2:
                fp->Value.Size = 2;
                if (row[i] == NULL)
                    *(fp->Value.Value.Signed2) = BIG_2;
                else
                    *(fp->Value.Value.Signed2) = atoi(row[i]);
                if (*(fp->Value.Value.Signed2) == BIG_2) {
                    fp->Value.IsNull = 1;
                    fp->Value.Size = 0;
                }
                break;
            case TBL_UNSIGNED2:
                fp->Value.Size = 2;
                if (row[i] == NULL)
                    *(fp->Value.Value.Unsigned2) = BIG_2;
                else
                    *(fp->Value.Value.Unsigned2) = atoi(row[i]);
                if (*(fp->Value.Value.Unsigned2) == BIG_2) {
                    fp->Value.IsNull = 1;
                    fp->Value.Size = 0;
                }
                break;
            case TBL_SIGNED4:
                fp->Value.Size = 4;
                if (row[i] == NULL)
                    *(fp->Value.Value.Signed4) = BIG_4;
                else
                    *(fp->Value.Value.Signed4) = atoi(row[i]);
                if (*(fp->Value.Value.Signed4) == BIG_4) {
                    fp->Value.IsNull = 1;
                    fp->Value.Size = 0;
                }
                break;
            case TBL_UNSIGNED4:
                fp->Value.Size = 4;
                if (row[i] == NULL)
                    *(fp->Value.Value.Unsigned4) = BIG_4;
                else
                    *(fp->Value.Value.Unsigned4) = atoi(row[i]);
                if (*(fp->Value.Value.Unsigned4) == BIG_4) {
                    fp->Value.IsNull = 1;
                    fp->Value.Size = 0;
                }
                break;
            case TBL_FLOAT4:
                fp->Value.Size = 4;
                if (row[i] == NULL)
                    *(fp->Value.Value.Float4) = BIG_4;
                else
                    *(fp->Value.Value.Float4) = atof(row[i]);
                if (*(fp->Value.Value.Float4) == BIG_4) {
                    fp->Value.IsNull = 1;
                    fp->Value.Size = 0;
                }
                break;
            case TBL_FLOAT8:
                fp->Value.Size = 8;
                if (row[i] == NULL)
                    *(fp->Value.Value.Float8) = BIG_4;
                else
                    *(fp->Value.Value.Float8) = atof(row[i]);
                if (*(fp->Value.Value.Float8) == BIG_4) {
                    fp->Value.IsNull = 1;
                    fp->Value.Size = 0;
                }
                break;
            case TBL_TEXT:
            case TBL_BINARYDATA:
            case TBL_STRING:
                fp->Value.Size = fp->Value.AllocatedSize;
                if (row[i] == NULL)
                    fp->Value.Value.String[0] = '\0';
                else
                    strncpy(fp->Value.Value.String, row[i], fp->Value.AllocatedSize - 1);
                if (strcmp(fp->Value.Value.String, "") == 0) {
                    fp->Value.IsNull = 1;
                    fp->Value.Size = 0;
                }
                break;
            }
        }
        if (callback != NULL) {
            if (callback(fieldList, *lp, ctx) != TBL_NORMAL) {
                mysqlfreebuf(&G_DBSelect);
                mysql_free_result(ans);
#ifdef CTN_USE_THREADS
                THR_ReleaseMutex();
#endif
                return COND_PushCondition(TBL_ERROR(TBL_EARLYEXIT), "TBL_Select");
            }
        }
    }

    mysqlfreebuf(&G_DBSelect);
    mysql_free_result(ans);
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex();
#endif
    return TBL_NORMAL;
}
Пример #16
0
/* TBL_NextUnique
**
** Purpose:
**	This routine retrieves the next unique number from a predefined table.
**
** Parameter Dictionary:
**	TBL_HANDLE **handle: The pointer for the database/table pair
**		to be accessed for modification.  This table must be open.
**	char *name : The name of the unique variable to access.
**	int *unique: Contains the next unique number in the sequence upon
**			return.
**
** Return Values:
**	TBL_NORMAL: normal termination.
**	TBL_BADHANDLE: The handle passed to the routine was invalid.
**	TBL_DBNOEXIST: The database specified does not exist.
**	TBL_SELECTFAILED: The unique number name could not be found.
**	TBL_UPDATEFAILED: The unique number could not be incremented.
**
** Notes:
**	Nothing unusual.
**
** Algorithm:
**	The unique number associated with  "name" in the opened table is
**	retrieved and passed back to the user in "unique".  This number is
**	then incremented (by one) and placed back in the table in preparation
**	for the next call to this routine.
*/
CONDITION
TBL_NextUnique(TBL_HANDLE ** handle, char *name, int *unique)
{
  TBL_CONTEXT* tc;
  TBL_FIELD* fp;
  char tabcol[100];
  char* dbName;
  char *tableName;
  int i;
  int ret;
  int FoundTextorBinary;
  int foundit;
  char selectCommand[2048];
  char updateCommand[2048];
  long realcount;
  long * lp;

  PGresult* res;
  PGconn* conn;
  int nTuples;

#ifdef CTN_USE_THREADS
    THR_ObtainMutex(FAC_TBL);
#endif

  tc = G_ContextHead;
  foundit = 0;
  while (tc != (TBL_CONTEXT *) NULL) {
    if (tc == (TBL_CONTEXT *) (*handle)) {
      dbName = tc->databaseName;
      tableName = tc->tableName;
      conn = (PGconn*)tc->dbSpecific;
      foundit = 1;
      break;
    }
    tc = tc->next;
  }
  if (!foundit) {
#ifdef CTN_USE_THREADS
    THR_ReleaseMutex(FAC_TBL);
#endif
    return COND_PushCondition(TBL_ERROR(TBL_BADHANDLE), "TBL_NextUnique");
  }
  res = PQexec(conn, "BEGIN");
  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
    fprintf(stderr, PQresultErrorMessage(res));
    exit(1);
  }
  PQclear(res);

  sprintf(selectCommand,
	  "SELECT UniqueNumber FROM %s WHERE NumberName=\'%s\'",
	  tableName,
	  name);
  res = PQexec(conn, selectCommand);
  if (PQresultStatus(res) != PGRES_TUPLES_OK) {
    fprintf(stderr, PQresultErrorMessage(res));
    fprintf(stderr, selectCommand);
    exit(1);
  }

  *unique = -1;
  nTuples = PQntuples(res);
  if (nTuples != 1) {
    fprintf(stderr, "Expected 1 tuples in TBL_NextUnique, got %d\n",
	    nTuples);
    exit(1);
  }
  *unique=atoi(PQgetvalue(res, 0, 0));
  PQclear(res);

  sprintf(updateCommand,
	  "UPDATE %s SET UniqueNumber=UniqueNumber+1 WHERE NumberName=\'%s\'",
	  tableName,
	  name);
  res = PQexec(conn, updateCommand);
  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
    fprintf(stderr, PQresultErrorMessage(res));
    fprintf(stderr, "%s\n", updateCommand);
    exit(1);
  }
  PQclear(res);

  res = PQexec(conn, "COMMIT");
  if (PQresultStatus(res) != PGRES_COMMAND_OK) {
    fprintf(stderr, PQresultErrorMessage(res));
    exit(1);
  }
  PQclear(res);

#ifdef CTN_USE_THREADS
  THR_ReleaseMutex(FAC_TBL);
#endif
  return TBL_NORMAL;
}
Пример #17
0
CONDITION
TBL_Open(const char *databaseName, const char *tableName, TBL_HANDLE ** handle)
{
    TBL_CONTEXT
    * tc;
    char
    *sn,
    server_name[50],
    *tdb,
    *ttb,
    *port;
    unsigned int
    port_number;

    (*handle) = (void *) NULL;

#ifdef CTN_USE_THREADS
    THR_ObtainMutex();
#endif

    tc = G_ContextHead;
    while (tc != (TBL_CONTEXT *) NULL) {
        if ((strcmp(tc->databaseName, databaseName) == 0) &&
                (strcmp(tc->tableName, tableName) == 0)) {
            tc->refCount++;
            (*handle) = (void *) tc;
            G_OpenFlag++;
#ifdef CTN_USE_THREADS
            THR_ReleaseMutex();
#endif
            return TBL_NORMAL;


            /* 27-May-1998, Allow multiple callers to have same open DB */
#if 0
            return COND_PushCondition(TBL_ERROR(TBL_ALREADYOPENED),
                                      "TBL_Open",
                                      databaseName, tableName);
#endif
        }
        tc = tc->next;
    }

    if (G_OpenFlag == 0) {
        if ((sn = getenv("CTN_MYSQL_SERVER")) == NULL)
            strcpy(server_name, "localhost");
        else
            strcpy(server_name, sn);
        if  ((port = getenv("CTN_MYSQL_SERVER_PORT")) == NULL)
            port_number = 0;
        else
            port_number = (unsigned int)atoi(port);

        mysql_init(&mysql);
        if ((G_Mysql_Handle = mysql_real_connect(&mysql, (char *) server_name, MYSQL_USER, MYSQL_PASSWORD, (char *) databaseName, port_number, NULL, 0)) == 0) {
            (void) COND_PushCondition(TBL_ERROR(TBL_DBSPECIFIC), "mySQL",
                                      mysql_error(&mysql), "TBL_Open");
#ifdef CTN_USE_THREADS
            THR_ReleaseMutex();
#endif
            return COND_PushCondition(TBL_ERROR(TBL_DBINITFAILED),
                                      DATABASE, "TBL_Open");
        }
    }
    /*
    if (mysql_select_db(G_Mysql_Handle, (char *) databaseName) != 0) {
    (void) COND_PushCondition(TBL_ERROR(TBL_DBSPECIFIC), "mySQL",
    			  mysql_error(&mysql), "TBL_Open");
    #ifdef CTN_USE_THREADS
    THR_ReleaseMutex();
    #endif
    return COND_PushCondition(TBL_ERROR(TBL_DBINITFAILED), DATABASE, "TBL_Open");
    }
    */
    /*
     * We have to assume at this point that everything will be ok...
     */
    if ((tc = (TBL_CONTEXT *) malloc(sizeof(TBL_CONTEXT))) == (TBL_CONTEXT *) NULL) {
#ifdef CTN_USE_THREADS
        THR_ReleaseMutex();
#endif
        return COND_PushCondition(TBL_ERROR(TBL_NOMEMORY), "TBL_Open");
    }
    if ((tdb = (char *) malloc(strlen(databaseName) + 1)) == (char *) NULL) {
        free(tc);
#ifdef CTN_USE_THREADS
        THR_ReleaseMutex();
#endif
        return COND_PushCondition(TBL_ERROR(TBL_NOMEMORY), "TBL_Open");
    }
    if ((ttb = (char *) malloc(strlen(tableName) + 1)) == (char *) NULL) {
        free(tc);
        free(tdb);
#ifdef CTN_USE_THREADS
        THR_ReleaseMutex();
#endif
        return COND_PushCondition(TBL_ERROR(TBL_NOMEMORY), "TBL_Open");
    }
    strcpy(tdb, databaseName);
    strcpy(ttb, tableName);
    tc->databaseName = tdb;
    tc->tableName = ttb;
    tc->refCount = 1;
    tc->next = G_ContextHead;
    G_ContextHead = tc;

    (*handle) = (void *) G_ContextHead;

    G_OpenFlag++;

#ifdef CTN_USE_THREADS
    THR_ReleaseMutex();
#endif
    return TBL_NORMAL;

}
Пример #18
0
static void *
runThread(void *arg)
{
    THREAD_STRUCT *s;
    CONDITION cond;
    CTNBOOLEAN abortFlag;
    int runMode;

    s = (THREAD_STRUCT *) arg;

    cond = DUL_AcknowledgeAssociationRQ(&s->association, s->service);
    if (cond != DUL_NORMAL) {
	COND_DumpConditions();
	//goto exitLabel;
    }
    if (s->verboseDUL)
	DUL_DumpParams(s->service);

    MString logDir(s->logDir);
    MString storageDir(s->storageDir);
    MString gpppsStorageDir = storageDir + "/gppps";

    MDBPostProcMgr ppmgr(s->dbName);
    MDICOMReactor reactor;
    MSOPHandler echoHandler;
    MLQuery queryHandler(ppmgr, logDir);
    MLGPSPS gPSPSHandler(ppmgr, logDir);
    MLGPPPS gPPPSHandler(ppmgr, logDir, gpppsStorageDir);

    reactor.registerHandler(&echoHandler, DICOM_SOPCLASSVERIFICATION);
    reactor.registerHandler(&queryHandler, DICOM_SOPGPWORKLIST_FIND);
    reactor.registerHandler(&gPSPSHandler, DICOM_SOPGPSPS);
    reactor.registerHandler(&gPPPSHandler, DICOM_SOPGPPPS);

    reactor.processRequests(&s->association, s->service);

exitLabel:
    abortFlag = s->abortFlag;
    runMode = s->runMode;
    DUL_ClearServiceParameters(s->service);
    free(s->service);
    free(s);
    if (runMode == MODE_FORK) {
	exit(0);
    } else if (runMode == MODE_THREAD) {
#ifdef CTN_USE_THREADS
	THR_ObtainMutex(FAC_ATH);
	completedThreads++;
	THR_ReleaseMutex(FAC_ATH);

#ifdef _MSC_VER
	_endthread();
#else
	pthread_exit(NULL);
#endif
#endif
    } else {
	return 0;
    }
    return 0;
}