📄 table.cpp
字号:
//
// SCTable: A class to represent a table in memory
//
//
#include <afxwin.h>
#include "EMBSQL.h"
void *SCTable::operator new(size_t size)
{
return shared_malloc(size);
}
void SCTable::operator delete(void *ptr)
{
shared_free((char*)ptr);
}
//
// Create a memory based SQL table
SCTable::SCTable(CString nm, SCColumn *cols[], int sz)
{
name = new SCString(nm);
columns = (SCColumn**)shared_malloc(sz * sizeof(SCColumn*));
for (int i=0;i<sz;i++) {
columns[i] = new SCColumn(cols[i]->Name(),cols[i]->Type(),cols[i]->Width());
}
nCols = sz;
rows = new SCCollection();
}
//
// Destructor for the memory based SQL table
SCTable::~SCTable()
{
DeleteAllRows();
for (int i=0;i<nCols;i++)
delete columns[i];
delete columns;
delete name;
}
//
// Return the name of this table
CString SCTable::Name()
{
return name->Value();
}
//
// Return the number of columns in this table
int SCTable::Columns()
{
return nCols;
}
SCColumn** SCTable::GetColumnInfo()
{
return (SCColumn**)columns;
}
//
// Given a name, not case sensitive, return the index of the column
int SCTable::Index(CString nm)
{
for (int i=0;i<nCols;i++) {
if (nm.CompareNoCase(columns[i]->Name()) == 0)
return i;
}
return -1;
}
//
// Given a non-case sensitive name, return the type of the column
int SCTable::Type(CString nm)
{
int i = Index(nm);
if (i < 0) return CUNDEFINED;
return columns[i]->Type();
}
//
// Given the index, return the type of the column
int SCTable::Type(int n)
{
if (n >= nCols)
return CUNDEFINED;
return columns[n]->Type();
}
//
// Given a non case-sensitive name, return the column
SCColumn* SCTable::Column(CString n)
{
int i = Index(n);
if (i < 0) return NULL;
return (SCColumn*)columns[i];
}
//
// Given an index, return the column
SCColumn* SCTable::Column(int n)
{
if (n >= nCols)
return NULL;
return (SCColumn*)columns[n];
}
//
// Adds a row from an array of columns, the columns being the set used in the
// intitialization of the table itself
bool SCTable::AddRow()
{
return AddRow((SCColumn**)columns);
}
//
// Adds a row from an array of columns, but note, creates a copy of the input.
// Number of columns must match the table's, and the names and types must match
// too.
bool SCTable::AddRow(SCColumn* cols[])
{
bool rc;
void *array[MAX_COLUMNS];
for (int i=0, j=0;i<nCols;i++) {
j = Index(cols[i]->Name());
array[j] = cols[i]->Value();
}
rc = AddRow((const void **)array);
return rc;
}
//
// Adds a row from array of void pointers, but note, creates a copy of the input
//
bool SCTable::AddRow(const void **newRow)
{
int eType = 0;
void **n = NULL;
char *c;
unsigned *u;
long *l;
double *f, *ff;
if (newRow == NULL)
return false;
n = (void **)shared_malloc(sizeof(void*) * nCols);
for (int i=0;i<nCols;i++) {
eType = columns[i]->Type();
switch (eType) {
case CTIME:
case CSTRING: // chars
c = shared_malloc(columns[i]->Width());
strcpy(c,(char*)newRow[i]);
n[i] = (void *)c;
break;
case CUNSIGNED: // unsigned
u = (unsigned *)shared_malloc(sizeof(unsigned));
*u = *(unsigned *) newRow[i];
n[i] = (void *)u;
break;
case CLONG: // long
case CINT:
l = (long*)shared_malloc(sizeof(long));
*l = *(long *) newRow[i];
n[i] = (void *)l;
break;
case CFLOAT: // float
f = (double*)shared_malloc(sizeof(double));
ff = (double*) newRow[i];
*f = *ff;
n[i] = (void *)f;
break;
}
}
rows->Add((CObject*)n);
return TRUE;
}
//
// Given a list of columns, with values attached, search the row data from 'start'
// and find the first row that matches.
int SCTable::RecordInTable(SCColumn* col[], int ops[], int nColumns, int start)
{
int columnsToCheck[MAX_COLUMNS];
int present = 0;
present = 0; // when present == nColumns, you have a match
for (int i=0, j = 0;i<nColumns;i++) { // load up the attribute indexes
j = Index(col[i]->Name());
columnsToCheck[i] = j;
}
for (i=start;i<rows->GetSize();i++) { // for each row in the table,
for (j=0;j<nColumns;j++) { // and for each attribute within the row
if (Compare(col[i],columns[j],ops[j])) // apply the operation to those 2 items
present++; // and record in present
}
if (present == nColumns) // if all columns checked match, return here
return i;
}
return -1; // incomplete or no match anywhere in table
}
//
// Given columns a and b, compare using operator op
int SCTable::Compare(SCColumn *a, SCColumn *b, int op)
{
int *inta = NULL, *intb = NULL;
double *da = NULL, *db = NULL;
unsigned *ua = NULL, *ub = NULL;
char *ca = NULL, *cb = NULL;
int c = 0;
if (a->Type() != b->Type()) // type mismatch, don't bother
return -1;
//
// Get the values to compare and do an equivalence match
//
switch(a->Type()) {
case CTIME:
case CSTRING:
ca = (char *)a->Value();
cb = (char *)b->Value();
c = strcmp(ca,cb);
break;
case CFLOAT:
da = (double* )a->Value();
db = (double* )b->Value();
c = (*da == *db);
break;
case CLONG:
case CINT:
inta = (int *)a->Value();
intb = (int *)b->Value();
c = (*inta == *intb);
break;
case CUNSIGNED:
ua = (unsigned *)a->Value();
ub = (unsigned *)b->Value();
c = (*ua == *ub);
break;
default:
return -2;
}
//
// Do the operation on the 2 values, based on the return values of the comparison
// and the type of attributes we are dealing with
//
switch(op) {
case CLT:
if (c < 0) return 1;
return 0;
case CLE:
if (c < 0 || c == 0) return 1;
return 0;
case CEQ:
if (c == 0) return 1;
return 0;
case CGT:
if (c > 0 || c == 0) return 1;
return 0;
case CGE:
if (c > 0) return 1;
}
return 0; // no match
}
//
// Return an array of data, representing one row in the table
void **SCTable::GetRow(int i)
{
void **r = NULL;
r = (void **)rows->GetAt(i);
return r;
}
//
// Delete a row in the table. Each row is an array of pointers. So, delete
// the pointers in the array, then the array itself. Then adjust the size
// of the row collection itself
bool SCTable::DeleteRow(int i)
{
void **rr = NULL;
if (i < 0 || i > rows->GetSize())
return false;
rr = (void **)rows->GetAt(i);
for (int j = 0;j<nCols;j++)
shared_free((char*)rr[j]);
shared_free((char*)rr);;
rows->RemoveAt(i);
return true;
}
//
// Delete all rows in the table
void SCTable::DeleteAllRows()
{
while(rows->GetSize() > 0)
DeleteRow(0);
}
//
// Return the number of rows int he table
int SCTable::NRows()
{
return rows->GetSize();
}
//
// Given a type and a void pointer, interpret as a floating point number
double SCTable::InterpretAsFloat(int type, void *ptr)
{
int inta = 0;
unsigned ua = 0;
switch(type) {
case CTIME:
case CSTRING:
return 0.0;
case CFLOAT:
return *(double *)ptr;
case CLONG:
case CINT:
inta = *(int *)ptr;
return (double) inta;
case CUNSIGNED:
ua = *(unsigned *)ptr;
return (double)ua;
}
return 0.0;
}
//
// Given a type and a void pointer, interpret as a string
CString* SCTable::InterpretAsString(int type, void *ptr)
{
char cbuf[128] = {""};
switch(type) {
case CTIME:
case CSTRING:
return new CString((char *)ptr);
case CFLOAT:
sprintf(cbuf,"%f", *(double *)ptr);
return new CString(cbuf);
case CLONG:
case CINT:
sprintf(cbuf,"%d",*(int *)ptr);
return new CString(cbuf);
case CUNSIGNED:
sprintf(cbuf,"%u",*(unsigned *)ptr);
return new CString(cbuf);
}
return new CString("");
}
//
// Print the indicated row in the table
bool SCTable::PrintRow(int which)
{
CString *s = NULL;
char format[128] = {""};
void *ptr = NULL, **row = NULL;
row = (void**)GetRow(which);
for (int i=0;i<nCols;i++) {
ptr = row[i];
s = InterpretAsString(columns[i]->Type(),ptr);
printf("%s\t",(LPCSTR)s);
delete s;
}
printf("\n");
return true;
}
//
// Given the row, print it using the columns of this table
bool SCTable::PrintRow(void **row)
{
CString *s = NULL;
char format[128] = {""};
void *ptr = NULL;
double f;
for (int i=0;i<nCols;i++) {
ptr = row[i];
f = *((double*)row[i]);
s = InterpretAsString(columns[i]->Type(),ptr);
printf("%s\t",(LPCSTR)*s);
delete s;
}
printf("\n");
return true;
}
//
// Given a column array, prrint the given row
bool SCTable::PrintRow(SCColumn** cols, int nC, void **row)
{
CString *s = NULL;
char format[128] = {""}, wid[16] = {""};
void *ptr = NULL;
if (!row || nC < 0) return false;
for (int i=0;i<nC;i++) {
ptr = row[i];
s = InterpretAsString(cols[i]->Type(),ptr);
sprintf(wid,"%d",cols[i]->Width());
strcpy(format,"% ");
strcat(format,wid);
strcat(format,"s ");
printf(format,*s);
delete s;
}
printf("\n");
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -