📄 emfdb.c
字号:
/*
* emfdb.c -- EMF database compatability functions for GoAhead WebServer.
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*
* $Id: emfdb.c,v 1.4 2003/09/29 19:48:08 bporter Exp $
*/
/******************************** Description *********************************/
/*
* Textfile-based database support for WebServer 2.1.
*/
/********************************* Includes ***********************************/
#include "emfdb.h"
#include "wsIntrn.h"
/********************************* Defines ************************************/
#define KEYWORD_TABLE T("TABLE")
#define KEYWORD_ROW T("ROW")
/*********************************** Locals ***********************************/
/*
* Variable to support the basicSet and basicGet functions.
*/
static char_t *basicProdDir = NULL;
static char_t *basicDefaultDir = T("."); /* Default set to current */
/*
* hAlloc chain list of table schemas to be closed
*/
static int dbMaxTables = 0;
static dbTable_t **dbListTables = NULL;
/****************************** Forward Declarations **************************/
static int crack(char_t *buf, char_t **key, char_t **val);
static char_t *trim(char_t *str);
static int GetColumnIndex(int tid, char_t *colName);
/******************************************************************************/
/*
* Add a schema to the module-internal schema database
*/
int dbRegisterDBSchema(dbTable_t *pTableRegister)
{
dbTable_t *pTable;
int tid;
a_assert(pTableRegister);
trace(4, T("DB: Registering database table <%s>\n"),
pTableRegister->name);
/*
* Bump up the size of the table array
*/
tid = hAllocEntry((void***) &dbListTables,
&dbMaxTables, sizeof(dbTable_t));
/*
* Copy the table schema to the last spot in schema array
*/
a_assert(dbListTables);
pTable = dbListTables[tid];
a_assert(pTable);
/*
* Copy the name of the table
*/
pTable->name = bstrdup(B_L, pTableRegister->name);
/*
* Copy the number of columns
*/
pTable->nColumns = pTableRegister->nColumns;
/*
* Copy the column definitions
*/
if (pTable->nColumns > 0) {
int i;
pTable->columnNames = balloc(B_L, sizeof(char_t *) * pTable->nColumns);
pTable->columnTypes = balloc(B_L, sizeof(int *) * pTable->nColumns);
for (i = 0; (i < pTableRegister->nColumns); i++) {
pTable->columnNames[i] =
bstrdup(B_L, pTableRegister->columnNames[i]);
pTable->columnTypes[i] = pTableRegister->columnTypes[i];
}
} else {
pTable->columnNames = NULL;
pTable->columnTypes = NULL;
}
/*
* Zero out the table's data (very important!)
*/
pTable->nRows = 0;
pTable->rows = NULL;
return 0;
}
/******************************************************************************/
/*
* This is provided for compatibility with EMF. Tables are "registered"
* with staticly defined schemas. There is only one did in this package: 0.
*/
int dbOpen(char_t *tablename, char_t *filename,
int (*gettime)(int did), int flags)
{
basicProdDir = NULL;
basicDefaultDir = T(".");
dbMaxTables = 0;
dbListTables = NULL;
return 0;
}
/******************************************************************************/
/*
* Delete all the rows of the tables, and all of the tables
*/
void dbClose(int did)
{
int table, column;
dbTable_t *pTable;
/*
* Before doing anything, delete all the contents of the database
*/
dbZero(did);
/*
* Now delete the tables
*/
for (table = 0; table < dbMaxTables; table++) {
pTable = dbListTables[table];
if (pTable != NULL) {
/*
* Delete the table schema
*/
if (pTable->nColumns) {
for (column = 0; column < pTable->nColumns; column++) {
bfreeSafe(B_L, pTable->columnNames[column]);
}
bfreeSafe(B_L, pTable->columnNames);
bfreeSafe(B_L, pTable->columnTypes);
}
/*
* Delete the table name
*/
bfreeSafe(B_L, pTable->name);
/*
* Free the table
*/
bfreeSafe(B_L, pTable);
hFree((void ***) &dbListTables, table);
}
}
if (dbListTables) {
bfree(B_L, dbListTables);
}
/*
* Set the global table list to a safe value
*/
dbListTables = NULL;
dbMaxTables = 0;
}
/******************************************************************************/
/*
* Delete all the data records in all tables
*/
void dbZero(int did)
{
int table, row, column, nRows, nColumns;
int *pRow;
dbTable_t *pTable;
/*
* Delete all data from all tables
*/
for (table = 0; table < dbMaxTables; table++) {
pTable = dbListTables[table];
/*
* Delete the row data contained within the schema
*/
if (pTable) {
nColumns = pTable->nColumns;
nRows = pTable->nRows;
for (row = 0; row < nRows; row++) {
pRow = pTable->rows[row];
if (pRow) {
/*
* Only delete the contents of rows not previously deleted!
*/
for (column = 0; column < nColumns; column++) {
if (pTable->columnTypes[column] == T_STRING) {
bfreeSafe(B_L, (char_t *)(pRow[column]));
pRow[column] = (int)NULL;
}
}
bfreeSafe(B_L, pRow);
hFree((void ***) &pTable->rows, row);
}
}
pTable->rows = NULL;
pTable->nRows = 0;
}
}
}
/******************************************************************************/
/*
* Find the a row in the table with the given string in the given column
*/
int dbSearchStr(int did, char_t *tablename,
char_t *colName, char_t *value, int flags)
{
int tid, nRows, nColumns, column;
int match = 0;
dbTable_t *pTable;
a_assert(tablename);
a_assert(colName);
a_assert(value);
tid = dbGetTableId(0, tablename);
a_assert(tid >= 0);
if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
pTable = dbListTables[tid];
} else {
return DB_ERR_TABLE_NOT_FOUND;
}
nColumns = pTable->nColumns;
nRows = pTable->nRows;
column = GetColumnIndex(tid, colName);
a_assert (column >= 0);
if (column >= 0) {
char_t *compareVal;
int row, *pRow;
/*
* Scan through rows until we find a match.
* Note that some of these rows may be deleted!
*/
row = 0;
while (row < nRows) {
pRow = pTable->rows[row];
if (pRow) {
compareVal = (char_t *)(pRow[column]);
if (NULL != compareVal)
{
if (DB_CASE_INSENSITIVE == flags)
{
match = gstricmp(compareVal, value);
}
else
{
match = gstrcmp(compareVal, value);
}
if (0 == match)
{
return row;
}
}
}
row++;
}
} else {
/*
* Return -2 if search column was not found
*/
trace(3, T("DB: Unable to find column <%s> in table <%s>\n"),
colName, tablename);
return DB_ERR_COL_NOT_FOUND;
}
return -1;
}
/******************************************************************************/
/*
* Add a new row to the given table. Return the new row ID.
*/
int dbAddRow(int did, char_t *tablename)
{
int tid, size;
dbTable_t *pTable;
a_assert(tablename);
tid = dbGetTableId(0, tablename);
a_assert(tid >= 0);
if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
pTable = dbListTables[tid];
} else {
return DB_ERR_TABLE_NOT_FOUND;
}
a_assert(pTable);
if (pTable) {
trace(5, T("DB: Adding a row to table <%s>\n"), tablename);
size = pTable->nColumns * max(sizeof(int), sizeof(char_t *));
return hAllocEntry((void***) &(pTable->rows), &(pTable->nRows), size);
}
return -1;
}
/******************************************************************************/
/*
* Delete a row in the table.
*/
int dbDeleteRow(int did, char_t *tablename, int row)
{
int tid, nColumns, nRows;
dbTable_t *pTable;
a_assert(tablename);
tid = dbGetTableId(0, tablename);
a_assert(tid >= 0);
if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
pTable = dbListTables[tid];
} else {
return DB_ERR_TABLE_NOT_FOUND;
}
nColumns = pTable->nColumns;
nRows = pTable->nRows;
if ((row >= 0) && (row < nRows)) {
int *pRow = pTable->rows[row];
if (pRow) {
int column = 0;
/*
* Free up any allocated strings
*/
while (column < nColumns) {
if (pRow[column] &&
(pTable->columnTypes[column] == T_STRING)) {
bfree(B_L, (char_t *)pRow[column]);
}
column++;
}
/*
* Zero out the row for safety
*/
memset(pRow, 0, nColumns * max(sizeof(int), sizeof(char_t *)));
bfreeSafe(B_L, pRow);
pTable->nRows = hFree((void ***)&pTable->rows, row);
trace(5, T("DB: Deleted row <%d> from table <%s>\n"),
row, tablename);
}
return 0;
} else {
trace(3, T("DB: Unable to delete row <%d> from table <%s>\n"),
row, tablename);
}
return -1;
}
/*****************************************************************************/
/*
* Grow the rows in the table to the nominated size.
*/
int dbSetTableNrow(int did, char_t *tablename, int nNewRows)
{
int nRet, tid, nRows, nColumns;
dbTable_t *pTable;
a_assert(tablename);
tid = dbGetTableId(0, tablename);
a_assert(tid >= 0) ;
if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
pTable = dbListTables[tid];
} else {
return DB_ERR_TABLE_NOT_FOUND;
}
nRet = -1;
a_assert(pTable);
if (pTable) {
nColumns = pTable->nColumns;
nRows = pTable->nRows;
nRet = 0;
if (nRows >= nNewRows) {
/*
* If number of rows already allocated exceeds requested number, do nothing
*/
trace(4, T("DB: Ignoring row set to <%d> in table <%s>\n"),
nNewRows, tablename);
} else {
trace(4, T("DB: Setting rows to <%d> in table <%s>\n"),
nNewRows, tablename);
while (pTable->nRows < nNewRows) {
if (dbAddRow(did, tablename) < 0) {
return -1;
}
}
}
}
return nRet;
}
/******************************************************************************/
/*
* Return the number of rows in the given table
*/
int dbGetTableNrow(int did, char_t *tablename)
{
int tid;
a_assert(tablename);
tid = dbGetTableId(did, tablename);
if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) {
return (dbListTables[tid])->nRows;
} else {
return -1;
}
}
/******************************************************************************/
/*
* Do table driven read of the database
*/
int dbReadInt(int did, char_t *table, char_t *column, int row, int *returnValue)
{
int colIndex, *pRow, tid;
dbTable_t *pTable;
a_assert(table);
a_assert(column);
a_assert(returnValue);
tid = dbGetTableId(0, table);
a_assert(tid >= 0);
/*
* Return -6 if table is not found
*/
if (tid < 0) {
return DB_ERR_TABLE_NOT_FOUND;
}
/*
* Return -7 if table id has been deleted
*/
pTable = dbListTables[tid];
if (pTable == NULL) {
return DB_ERR_TABLE_DELETED;
}
a_assert(row >= 0);
if ((row >= 0) && (row < pTable->nRows)) {
colIndex = GetColumnIndex(tid, column);
a_assert(colIndex >= 0);
if (colIndex >= 0) {
pRow = pTable->rows[row];
if (pRow) {
*returnValue = pRow[colIndex];
return 0;
}
return DB_ERR_ROW_DELETED;
}
return DB_ERR_COL_NOT_FOUND;
}
return DB_ERR_ROW_NOT_FOUND;
}
/******************************************************************************/
/*
* dbReadStr calls dbReadInt to do table driven read of database
*/
int dbReadStr(int did, char_t *table, char_t *column, int row,
char_t **returnValue)
{
return dbReadInt(did, table, column, row, (int *)returnValue);
}
/******************************************************************************/
/*
* The dbWriteInt function writes a value into a table at a given row and
* column. The existence of the row and column is verified before the
* write. 0 is returned on succes, -1 is returned on error.
*/
int dbWriteInt(int did, char_t *table, char_t *column, int row, int iData)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -