• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

DS_Table.cpp

Go to the documentation of this file.
00001 #include "DS_Table.h"
00002 #include "DS_OrderedList.h"
00003 #include <string.h>
00004 #include "RakAssert.h"
00005 #include "RakAssert.h"
00006 #include "Itoa.h"
00007 
00008 using namespace DataStructures;
00009 
00010 #ifdef _MSC_VER
00011 #pragma warning( push )
00012 #endif
00013 
00014 void ExtendRows(Table::Row* input, int index)
00015 {
00016         (void) index;
00017         input->cells.Insert(RakNet::OP_NEW<Table::Cell>(__FILE__, __LINE__), __FILE__, __LINE__ );
00018 }
00019 void FreeRow(Table::Row* input, int index)
00020 {
00021         (void) index;
00022 
00023         unsigned i;
00024         for (i=0; i < input->cells.Size(); i++)
00025         {
00026                 RakNet::OP_DELETE(input->cells[i], __FILE__, __LINE__);
00027         }
00028         RakNet::OP_DELETE(input, __FILE__, __LINE__);
00029 }
00030 Table::Cell::Cell()
00031 {
00032         isEmpty=true;
00033         c=0;
00034         ptr=0;
00035         i=0.0;
00036 }
00037 Table::Cell::~Cell()
00038 {
00039         Clear();
00040 }
00041 Table::Cell& Table::Cell::operator = ( const Table::Cell& input )
00042 {
00043         isEmpty=input.isEmpty;
00044         i=input.i;
00045         ptr=input.ptr;
00046         if (c)
00047                 rakFree_Ex(c, __FILE__, __LINE__);
00048         if (input.c)
00049         {
00050                 c = (char*) rakMalloc_Ex( (int) i, __FILE__, __LINE__ );
00051                 memcpy(c, input.c, (int) i);
00052         }
00053         else
00054                 c=0;
00055         return *this;
00056 }
00057 Table::Cell::Cell( const Table::Cell & input)
00058 {
00059         isEmpty=input.isEmpty;
00060         i=input.i;
00061         ptr=input.ptr;
00062         if (input.c)
00063         {
00064                 if (c)
00065                         rakFree_Ex(c, __FILE__, __LINE__);
00066                 c =  (char*) rakMalloc_Ex( (int) i, __FILE__, __LINE__ );
00067                 memcpy(c, input.c, (int) i);
00068         }
00069 }
00070 void Table::Cell::Set(double input)
00071 {
00072         Clear();
00073         i=input;
00074         c=0;
00075         ptr=0;
00076         isEmpty=false;
00077 }
00078 void Table::Cell::Set(unsigned int input)
00079 {
00080         Set((int) input);
00081 }
00082 void Table::Cell::Set(int input)
00083 {
00084         Clear();
00085         i=(double) input;
00086         c=0;
00087         ptr=0;
00088         isEmpty=false;
00089 }
00090 
00091 void Table::Cell::Set(const char *input)
00092 {
00093         Clear();
00094                 
00095         if (input)
00096         {
00097                 i=(int)strlen(input)+1;
00098                 c =  (char*) rakMalloc_Ex( (int) i, __FILE__, __LINE__ );
00099                 strcpy(c, input);
00100         }
00101         else
00102         {
00103                 c=0;
00104                 i=0;
00105         }
00106         ptr=0;
00107         isEmpty=false;
00108 }
00109 void Table::Cell::Set(const char *input, int inputLength)
00110 {
00111         Clear();
00112         if (input)
00113         {
00114                 c = (char*) rakMalloc_Ex( inputLength, __FILE__, __LINE__ );
00115                 i=inputLength;
00116                 memcpy(c, input, inputLength);
00117         }
00118         else
00119         {
00120                 c=0;
00121                 i=0;
00122         }
00123         ptr=0;
00124         isEmpty=false;
00125 }
00126 void Table::Cell::SetPtr(void* p)
00127 {
00128         Clear();
00129         c=0;
00130         ptr=p;
00131         isEmpty=false;
00132 }
00133 void Table::Cell::Get(int *output)
00134 {
00135         RakAssert(isEmpty==false);
00136         int o = (int) i;
00137         *output=o;
00138 }
00139 void Table::Cell::Get(double *output)
00140 {
00141         RakAssert(isEmpty==false);
00142         *output=i;
00143 }
00144 void Table::Cell::Get(char *output)
00145 {
00146         RakAssert(isEmpty==false);
00147         strcpy(output, c);
00148 }
00149 void Table::Cell::Get(char *output, int *outputLength)
00150 {
00151         RakAssert(isEmpty==false);
00152         memcpy(output, c, (int) i);
00153         if (outputLength)
00154                 *outputLength=(int) i;
00155 }
00156 RakNet::RakString Table::Cell::ToString(ColumnType columnType)
00157 {
00158         if (isEmpty)
00159                 return RakNet::RakString();
00160 
00161         if (columnType==NUMERIC)
00162         {
00163                 return RakNet::RakString("%f", i);
00164         }
00165         else if (columnType==STRING)
00166         {
00167                 return RakNet::RakString(c);
00168         }
00169         else if (columnType==BINARY)
00170         {
00171                 return RakNet::RakString("<Binary>");
00172         }
00173         else if (columnType==POINTER)
00174         {
00175                 return RakNet::RakString("%p", ptr);
00176         }
00177 
00178         return RakNet::RakString();
00179 }
00180 Table::Cell::Cell(double numericValue, char *charValue, void *ptr, ColumnType type)
00181 {
00182         SetByType(numericValue,charValue,ptr,type);
00183 }
00184 void Table::Cell::SetByType(double numericValue, char *charValue, void *ptr, ColumnType type)
00185 {
00186         isEmpty=true;
00187         if (type==NUMERIC)
00188         {
00189                 Set(numericValue);
00190         }
00191         else if (type==STRING)
00192         {
00193                 Set(charValue);
00194         }
00195         else if (type==BINARY)
00196         {
00197                 Set(charValue, (int) numericValue);
00198         }
00199         else if (type==POINTER)
00200         {
00201                 SetPtr(ptr);
00202         }
00203         else
00204         {
00205                 ptr=(void*) charValue;
00206         }
00207 }
00208 Table::ColumnType Table::Cell::EstimateColumnType(void) const
00209 {
00210         if (c)
00211                 if (i!=0.0f)
00212                         return BINARY;
00213                 else
00214                         return STRING;
00215         if (ptr)
00216                 return POINTER;
00217         return NUMERIC;
00218 }
00219 void Table::Cell::Clear(void)
00220 {
00221         if (isEmpty==false && c)
00222         {
00223                 rakFree_Ex(c, __FILE__, __LINE__);
00224                 c=0;
00225         }
00226         isEmpty=true;
00227 }
00228 Table::ColumnDescriptor::ColumnDescriptor()
00229 {
00230 
00231 }
00232 Table::ColumnDescriptor::~ColumnDescriptor()
00233 {
00234 
00235 }
00236 Table::ColumnDescriptor::ColumnDescriptor(const char cn[_TABLE_MAX_COLUMN_NAME_LENGTH], ColumnType ct)
00237 {
00238         columnType=ct;
00239         strcpy(columnName, cn);
00240 }
00241 void Table::Row::UpdateCell(unsigned columnIndex, double value)
00242 {
00243         cells[columnIndex]->Clear();
00244         cells[columnIndex]->Set(value);
00245 
00246 //      cells[columnIndex]->i=value;
00247 //      cells[columnIndex]->c=0;
00248 //      cells[columnIndex]->isEmpty=false;
00249 }
00250 void Table::Row::UpdateCell(unsigned columnIndex, const char *str)
00251 {
00252         cells[columnIndex]->Clear();
00253         cells[columnIndex]->Set(str);
00254 }
00255 void Table::Row::UpdateCell(unsigned columnIndex, int byteLength, const char *data)
00256 {
00257         cells[columnIndex]->Clear();
00258         cells[columnIndex]->Set(data,byteLength);
00259 }
00260 Table::Table()
00261 {
00262 }
00263 Table::~Table()
00264 {
00265         Clear();
00266 }
00267 unsigned Table::AddColumn(const char columnName[_TABLE_MAX_COLUMN_NAME_LENGTH], ColumnType columnType)
00268 {
00269         if (columnName[0]==0)
00270                 return (unsigned) -1;
00271 
00272         // Add this column.
00273         columns.Insert(Table::ColumnDescriptor(columnName, columnType), __FILE__, __LINE__);
00274 
00275         // Extend the rows by one
00276         rows.ForEachData(ExtendRows);
00277 
00278         return columns.Size()-1;
00279 }
00280 void Table::RemoveColumn(unsigned columnIndex)
00281 {
00282         if (columnIndex >= columns.Size())
00283                 return;
00284 
00285         columns.RemoveAtIndex(columnIndex);
00286 
00287         // Remove this index from each row.
00288         int i;
00289         DataStructures::Page<unsigned, Row*, _TABLE_BPLUS_TREE_ORDER> *cur = rows.GetListHead();
00290         while (cur)
00291         {
00292                 for (i=0; i < cur->size; i++)
00293                 {
00294                         RakNet::OP_DELETE(cur->data[i]->cells[columnIndex], __FILE__, __LINE__);
00295                         cur->data[i]->cells.RemoveAtIndex(columnIndex);
00296                 }
00297 
00298                 cur=cur->next;
00299         }
00300 }
00301 unsigned Table::ColumnIndex(const char *columnName) const
00302 {
00303         unsigned columnIndex;
00304         for (columnIndex=0; columnIndex<columns.Size(); columnIndex++)
00305                 if (strcmp(columnName, columns[columnIndex].columnName)==0)
00306                         return columnIndex;
00307         return (unsigned)-1;
00308 }
00309 unsigned Table::ColumnIndex(char columnName[_TABLE_MAX_COLUMN_NAME_LENGTH]) const
00310 {
00311         return ColumnIndex((const char *) columnName);
00312 }
00313 char* Table::ColumnName(unsigned index) const
00314 {
00315         if (index >= columns.Size())
00316                 return 0;
00317         else
00318                 return (char*)columns[index].columnName;
00319 }
00320 Table::ColumnType Table::GetColumnType(unsigned index) const
00321 {
00322         if (index >= columns.Size())
00323                 return (Table::ColumnType) 0;
00324         else
00325                 return columns[index].columnType;
00326 }
00327 unsigned Table::GetColumnCount(void) const
00328 {
00329         return columns.Size();
00330 }
00331 unsigned Table::GetRowCount(void) const
00332 {
00333         return rows.Size();
00334 }
00335 Table::Row* Table::AddRow(unsigned rowId)
00336 {
00337         Row *newRow;
00338         newRow = RakNet::OP_NEW<Row>( __FILE__, __LINE__ );
00339         if (rows.Insert(rowId, newRow)==false)
00340         {
00341                 RakNet::OP_DELETE(newRow, __FILE__, __LINE__);
00342                 return 0; // Already exists
00343         }
00344         unsigned rowIndex;
00345         for (rowIndex=0; rowIndex < columns.Size(); rowIndex++)
00346                 newRow->cells.Insert( RakNet::OP_NEW<Table::Cell>(__FILE__, __LINE__), __FILE__, __LINE__ );
00347         return newRow;
00348 }
00349 Table::Row* Table::AddRow(unsigned rowId, DataStructures::List<Cell> &initialCellValues)
00350 {
00351         Row *newRow = RakNet::OP_NEW<Row>( __FILE__, __LINE__ );
00352         unsigned rowIndex;
00353         for (rowIndex=0; rowIndex < columns.Size(); rowIndex++)
00354         {
00355                 if (rowIndex < initialCellValues.Size() && initialCellValues[rowIndex].isEmpty==false)
00356                 {
00357                         Table::Cell *c;
00358                         c = RakNet::OP_NEW<Table::Cell>(__FILE__, __LINE__);
00359                         c->SetByType(initialCellValues[rowIndex].i,initialCellValues[rowIndex].c,initialCellValues[rowIndex].ptr,columns[rowIndex].columnType);
00360                         newRow->cells.Insert(c, __FILE__, __LINE__ );
00361                 }
00362                 else
00363                         newRow->cells.Insert(RakNet::OP_NEW<Table::Cell>(__FILE__, __LINE__), __FILE__, __LINE__ );
00364         }
00365         rows.Insert(rowId, newRow);
00366         return newRow;
00367 }
00368 Table::Row* Table::AddRow(unsigned rowId, DataStructures::List<Cell*> &initialCellValues, bool copyCells)
00369 {
00370         Row *newRow = RakNet::OP_NEW<Row>( __FILE__, __LINE__ );
00371         unsigned rowIndex;
00372         for (rowIndex=0; rowIndex < columns.Size(); rowIndex++)
00373         {
00374                 if (rowIndex < initialCellValues.Size() && initialCellValues[rowIndex] && initialCellValues[rowIndex]->isEmpty==false)
00375                 {
00376                         if (copyCells==false)
00377                                 newRow->cells.Insert(RakNet::OP_NEW_4<Table::Cell>( __FILE__, __LINE__, initialCellValues[rowIndex]->i, initialCellValues[rowIndex]->c, initialCellValues[rowIndex]->ptr, columns[rowIndex].columnType), __FILE__, __LINE__);
00378                         else
00379                         {
00380                                 Table::Cell *c = RakNet::OP_NEW<Table::Cell>( __FILE__, __LINE__ );
00381                                 newRow->cells.Insert(c, __FILE__, __LINE__);
00382                                 *c=*(initialCellValues[rowIndex]);
00383                         }
00384                 }
00385                 else
00386                         newRow->cells.Insert(RakNet::OP_NEW<Table::Cell>(__FILE__, __LINE__), __FILE__, __LINE__);
00387         }
00388         rows.Insert(rowId, newRow);
00389         return newRow;
00390 }
00391 Table::Row* Table::AddRowColumns(unsigned rowId, Row *row, DataStructures::List<unsigned> columnIndices)
00392 {
00393         Row *newRow = RakNet::OP_NEW<Row>( __FILE__, __LINE__ );
00394         unsigned columnIndex;
00395         for (columnIndex=0; columnIndex < columnIndices.Size(); columnIndex++)
00396         {
00397                 if (row->cells[columnIndices[columnIndex]]->isEmpty==false)
00398                 {
00399                         newRow->cells.Insert(RakNet::OP_NEW_4<Table::Cell>( __FILE__, __LINE__, 
00400                                 row->cells[columnIndices[columnIndex]]->i,
00401                                 row->cells[columnIndices[columnIndex]]->c,
00402                                 row->cells[columnIndices[columnIndex]]->ptr,
00403                                 columns[columnIndex].columnType
00404                                 ), __FILE__, __LINE__);
00405                 }
00406                 else
00407                 {
00408                         newRow->cells.Insert(RakNet::OP_NEW<Table::Cell>(__FILE__, __LINE__), __FILE__, __LINE__);
00409                 }
00410         }
00411         rows.Insert(rowId, newRow);
00412         return newRow;
00413 }
00414 bool Table::RemoveRow(unsigned rowId)
00415 {
00416         Row *out;
00417         if (rows.Delete(rowId, out))
00418         {
00419                 DeleteRow(out);
00420                 return true;
00421         }
00422         return false;
00423 }
00424 void Table::RemoveRows(Table *tableContainingRowIDs)
00425 {
00426         unsigned i;
00427         DataStructures::Page<unsigned, Row*, _TABLE_BPLUS_TREE_ORDER> *cur = tableContainingRowIDs->GetRows().GetListHead();
00428         while (cur)
00429         {
00430                 for (i=0; i < (unsigned)cur->size; i++)
00431                 {
00432                         rows.Delete(cur->keys[i]);
00433                 }
00434                 cur=cur->next;
00435         }
00436         return;
00437 }
00438 bool Table::UpdateCell(unsigned rowId, unsigned columnIndex, int value)
00439 {
00440         RakAssert(columns[columnIndex].columnType==NUMERIC);
00441 
00442         Row *row = GetRowByID(rowId);
00443         if (row)
00444         {
00445                 row->UpdateCell(columnIndex, value);
00446                 return true;
00447         }
00448         return false;
00449 }
00450 bool Table::UpdateCell(unsigned rowId, unsigned columnIndex, char *str)
00451 {
00452         RakAssert(columns[columnIndex].columnType==STRING);
00453 
00454         Row *row = GetRowByID(rowId);
00455         if (row)
00456         {
00457                 row->UpdateCell(columnIndex, str);
00458                 return true;
00459         }
00460         return false;
00461 }
00462 bool Table::UpdateCell(unsigned rowId, unsigned columnIndex, int byteLength, char *data)
00463 {
00464         RakAssert(columns[columnIndex].columnType==BINARY);
00465 
00466         Row *row = GetRowByID(rowId);
00467         if (row)
00468         {
00469                 row->UpdateCell(columnIndex, byteLength, data);
00470                 return true;
00471         }
00472         return false;
00473 }
00474 bool Table::UpdateCellByIndex(unsigned rowIndex, unsigned columnIndex, int value)
00475 {
00476         RakAssert(columns[columnIndex].columnType==NUMERIC);
00477 
00478         Row *row = GetRowByIndex(rowIndex,0);
00479         if (row)
00480         {
00481                 row->UpdateCell(columnIndex, value);
00482                 return true;
00483         }
00484         return false;
00485 }
00486 bool Table::UpdateCellByIndex(unsigned rowIndex, unsigned columnIndex, char *str)
00487 {
00488         RakAssert(columns[columnIndex].columnType==STRING);
00489 
00490         Row *row = GetRowByIndex(rowIndex,0);
00491         if (row)
00492         {
00493                 row->UpdateCell(columnIndex, str);
00494                 return true;
00495         }
00496         return false;
00497 }
00498 bool Table::UpdateCellByIndex(unsigned rowIndex, unsigned columnIndex, int byteLength, char *data)
00499 {
00500         RakAssert(columns[columnIndex].columnType==BINARY);
00501 
00502         Row *row = GetRowByIndex(rowIndex,0);
00503         if (row)
00504         {
00505                 row->UpdateCell(columnIndex, byteLength, data);
00506                 return true;
00507         }
00508         return false;
00509 }
00510 void Table::GetCellValueByIndex(unsigned rowIndex, unsigned columnIndex, int *output)
00511 {
00512         RakAssert(columns[columnIndex].columnType==NUMERIC);
00513 
00514         Row *row = GetRowByIndex(rowIndex,0);
00515         if (row)
00516         {
00517                 row->cells[columnIndex]->Get(output);
00518         }
00519 }
00520 void Table::GetCellValueByIndex(unsigned rowIndex, unsigned columnIndex, char *output)
00521 {
00522         RakAssert(columns[columnIndex].columnType==STRING);
00523 
00524         Row *row = GetRowByIndex(rowIndex,0);
00525         if (row)
00526         {
00527                 row->cells[columnIndex]->Get(output);
00528         }
00529 }
00530 void Table::GetCellValueByIndex(unsigned rowIndex, unsigned columnIndex, char *output, int *outputLength)
00531 {
00532         RakAssert(columns[columnIndex].columnType==BINARY);
00533 
00534         Row *row = GetRowByIndex(rowIndex,0);
00535         if (row)
00536         {
00537                 row->cells[columnIndex]->Get(output, outputLength);
00538         }
00539 }
00540 Table::FilterQuery::FilterQuery()
00541 {
00542         columnName[0]=0;
00543 }
00544 Table::FilterQuery::~FilterQuery()
00545 {
00546 
00547 }
00548 Table::FilterQuery::FilterQuery(unsigned column, Cell *cell, FilterQueryType op)
00549 {
00550         columnIndex=column;
00551         cellValue=cell;
00552         operation=op;
00553 }
00554 Table::Row* Table::GetRowByID(unsigned rowId) const
00555 {
00556         Row *row;
00557         if (rows.Get(rowId, row))
00558                 return row;
00559         return 0;
00560 }
00561 
00562 Table::Row* Table::GetRowByIndex(unsigned rowIndex, unsigned *key) const
00563 {
00564         DataStructures::Page<unsigned, Row*, _TABLE_BPLUS_TREE_ORDER> *cur = rows.GetListHead();
00565         while (cur)
00566         {
00567                 if (rowIndex < (unsigned)cur->size)
00568                 {
00569                         if (key)
00570                                 *key=cur->keys[rowIndex];
00571                         return cur->data[rowIndex];
00572                 }
00573                 if (rowIndex <= (unsigned)cur->size)
00574                         rowIndex-=cur->size;
00575                 else
00576                         return 0;
00577                 cur=cur->next;
00578         }
00579         return 0;
00580 }
00581 
00582 void Table::QueryTable(unsigned *columnIndicesSubset, unsigned numColumnSubset, FilterQuery *inclusionFilters, unsigned numInclusionFilters, unsigned *rowIds, unsigned numRowIDs, Table *result)
00583 {
00584         unsigned i;
00585         DataStructures::List<unsigned> columnIndicesToReturn;
00586 
00587         // Clear the result table.
00588         result->Clear();
00589 
00590         if (columnIndicesSubset && numColumnSubset>0)
00591         {
00592                 for (i=0; i < numColumnSubset; i++)
00593                 {
00594                         if (columnIndicesSubset[i]<columns.Size())
00595                                 columnIndicesToReturn.Insert(columnIndicesSubset[i], __FILE__, __LINE__);
00596                 }
00597         }
00598         else
00599         {
00600                 for (i=0; i < columns.Size(); i++)
00601                         columnIndicesToReturn.Insert(i, __FILE__, __LINE__);
00602         }
00603 
00604         if (columnIndicesToReturn.Size()==0)
00605                 return; // No valid columns specified
00606 
00607         for (i=0; i < columnIndicesToReturn.Size(); i++)
00608         {
00609                 result->AddColumn(columns[columnIndicesToReturn[i]].columnName,columns[columnIndicesToReturn[i]].columnType);
00610         }
00611 
00612         // Get the column indices of the filter queries.
00613         DataStructures::List<unsigned> inclusionFilterColumnIndices;
00614         if (inclusionFilters && numInclusionFilters>0)
00615         {
00616                 for (i=0; i < numInclusionFilters; i++)
00617                 {
00618                         if (inclusionFilters[i].columnName[0])
00619                                 inclusionFilters[i].columnIndex=ColumnIndex(inclusionFilters[i].columnName);
00620                         if (inclusionFilters[i].columnIndex<columns.Size())
00621                                 inclusionFilterColumnIndices.Insert(inclusionFilters[i].columnIndex, __FILE__, __LINE__);
00622                         else
00623                                 inclusionFilterColumnIndices.Insert((unsigned)-1, __FILE__, __LINE__);
00624                 }
00625         }
00626 
00627         if (rowIds==0 || numRowIDs==0)
00628         {
00629                 // All rows
00630                 DataStructures::Page<unsigned, Row*, _TABLE_BPLUS_TREE_ORDER> *cur = rows.GetListHead();
00631                 while (cur)
00632                 {
00633                         for (i=0; i < (unsigned)cur->size; i++)
00634                         {
00635                                 QueryRow(inclusionFilterColumnIndices, columnIndicesToReturn, cur->keys[i], cur->data[i], inclusionFilters, result);
00636                         }
00637                         cur=cur->next;
00638                 }
00639         }
00640         else
00641         {
00642                 // Specific rows
00643                 Row *row;
00644                 for (i=0; i < numRowIDs; i++)
00645                 {
00646                         if (rows.Get(rowIds[i], row))
00647                         {
00648                                 QueryRow(inclusionFilterColumnIndices, columnIndicesToReturn, rowIds[i], row, inclusionFilters, result);
00649                         }
00650                 }
00651         }
00652 }
00653 
00654 void Table::QueryRow(DataStructures::List<unsigned> &inclusionFilterColumnIndices, DataStructures::List<unsigned> &columnIndicesToReturn, unsigned key, Table::Row* row, FilterQuery *inclusionFilters, Table *result)
00655 {
00656         bool pass=false;
00657         unsigned columnIndex;
00658         unsigned j;
00659 
00660         // If no inclusion filters, just add the row
00661         if (inclusionFilterColumnIndices.Size()==0)
00662         {
00663                 result->AddRowColumns(key, row, columnIndicesToReturn);
00664         }
00665         else
00666         {
00667                 // Go through all inclusion filters.  Only add this row if all filters pass.
00668                 for (j=0; j<inclusionFilterColumnIndices.Size(); j++)
00669                 {
00670                         columnIndex=inclusionFilterColumnIndices[j];
00671                         if (columnIndex!=(unsigned)-1 && row->cells[columnIndex]->isEmpty==false )
00672                         {
00673                                 if (columns[inclusionFilterColumnIndices[j]].columnType==STRING &&
00674                                         (row->cells[columnIndex]->c==0 ||
00675                                         inclusionFilters[j].cellValue->c==0)    )
00676                                         continue;
00677 
00678                                 switch (inclusionFilters[j].operation)
00679                                 {
00680                                 case QF_EQUAL:
00681                                         switch(columns[inclusionFilterColumnIndices[j]].columnType)
00682                                         {
00683                                         case NUMERIC:
00684                                                 pass=row->cells[columnIndex]->i==inclusionFilters[j].cellValue->i;
00685                                                 break;
00686                                         case STRING:
00687                                                 pass=strcmp(row->cells[columnIndex]->c,inclusionFilters[j].cellValue->c)==0;
00688                                                 break;
00689                                         case BINARY:
00690                                                 pass=row->cells[columnIndex]->i==inclusionFilters[j].cellValue->i &&
00691                                                         memcmp(row->cells[columnIndex]->c,inclusionFilters[j].cellValue->c, (int) row->cells[columnIndex]->i)==0;
00692                                                 break;
00693                                         case POINTER:
00694                                                 pass=row->cells[columnIndex]->ptr==inclusionFilters[j].cellValue->ptr;
00695                                                 break;
00696                                         }
00697                                         break;
00698                                 case QF_NOT_EQUAL:
00699                                         switch(columns[inclusionFilterColumnIndices[j]].columnType)
00700                                         {
00701                                         case NUMERIC:
00702                                                 pass=row->cells[columnIndex]->i!=inclusionFilters[j].cellValue->i;
00703                                                 break;
00704                                         case STRING:
00705                                                 pass=strcmp(row->cells[columnIndex]->c,inclusionFilters[j].cellValue->c)!=0;
00706                                                 break;
00707                                         case BINARY:
00708                                                 pass=row->cells[columnIndex]->i==inclusionFilters[j].cellValue->i &&
00709                                                         memcmp(row->cells[columnIndex]->c,inclusionFilters[j].cellValue->c, (int) row->cells[columnIndex]->i)==0;
00710                                                 break;
00711                                         case POINTER:
00712                                                 pass=row->cells[columnIndex]->ptr!=inclusionFilters[j].cellValue->ptr;
00713                                                 break;
00714                                         }
00715                                         break;
00716                                 case QF_GREATER_THAN:
00717                                         switch(columns[inclusionFilterColumnIndices[j]].columnType)
00718                                         {
00719                                         case NUMERIC:
00720                                                 pass=row->cells[columnIndex]->i>inclusionFilters[j].cellValue->i;
00721                                                 break;
00722                                         case STRING:
00723                                                 pass=strcmp(row->cells[columnIndex]->c,inclusionFilters[j].cellValue->c)>0;
00724                                                 break;
00725                                         case BINARY:
00726                                         break;
00727                                         case POINTER:
00728                                                 pass=row->cells[columnIndex]->ptr>inclusionFilters[j].cellValue->ptr;
00729                                                 break;
00730                                         }
00731                                         break;
00732                                 case QF_GREATER_THAN_EQ:
00733                                         switch(columns[inclusionFilterColumnIndices[j]].columnType)
00734                                         {
00735                                         case NUMERIC:
00736                                                 pass=row->cells[columnIndex]->i>=inclusionFilters[j].cellValue->i;
00737                                                 break;
00738                                         case STRING:
00739                                                 pass=strcmp(row->cells[columnIndex]->c,inclusionFilters[j].cellValue->c)>=0;
00740                                                 break;
00741                                         case BINARY:
00742                                                 break;
00743                                         case POINTER:
00744                                                 pass=row->cells[columnIndex]->ptr>=inclusionFilters[j].cellValue->ptr;
00745                                                 break;
00746                                         }
00747                                         break;
00748                                 case QF_LESS_THAN:
00749                                         switch(columns[inclusionFilterColumnIndices[j]].columnType)
00750                                         {
00751                                         case NUMERIC:
00752                                                 pass=row->cells[columnIndex]->i<inclusionFilters[j].cellValue->i;
00753                                                 break;
00754                                         case STRING:
00755                                                 pass=strcmp(row->cells[columnIndex]->c,inclusionFilters[j].cellValue->c)<0;
00756                                                 break;
00757                                         case BINARY:
00758                                           break;
00759                                         case POINTER:
00760                                                 pass=row->cells[columnIndex]->ptr<inclusionFilters[j].cellValue->ptr;
00761                                                 break;
00762                                         }
00763                                         break;
00764                                 case QF_LESS_THAN_EQ:
00765                                         switch(columns[inclusionFilterColumnIndices[j]].columnType)
00766                                         {
00767                                         case NUMERIC:
00768                                                 pass=row->cells[columnIndex]->i<=inclusionFilters[j].cellValue->i;
00769                                                 break;
00770                                         case STRING:
00771                                                 pass=strcmp(row->cells[columnIndex]->c,inclusionFilters[j].cellValue->c)<=0;
00772                                                 break;
00773                                         case BINARY:
00774                                                 break;
00775                                         case POINTER:
00776                                                 pass=row->cells[columnIndex]->ptr<=inclusionFilters[j].cellValue->ptr;
00777                                                 break;
00778                                         }
00779                                         break;
00780                                 case QF_IS_EMPTY:
00781                                         pass=false;
00782                                         break;
00783                                 case QF_NOT_EMPTY:
00784                                         pass=true;
00785                                         break;
00786                                 default:
00787                                         pass=false;
00788                                         RakAssert(0);
00789                                         break;
00790                                 }
00791                         }
00792                         else
00793                         {
00794                                 if (inclusionFilters[j].operation==QF_IS_EMPTY)
00795                                         pass=true;
00796                                 else
00797                                         pass=false; // No value for this cell
00798                         }
00799 
00800                         if (pass==false)
00801                                 break;
00802                 }
00803 
00804                 if (pass)
00805                 {
00806                         result->AddRowColumns(key, row, columnIndicesToReturn);
00807                 }
00808         }
00809 }
00810 
00811 static Table::SortQuery *_sortQueries;
00812 static unsigned _numSortQueries;
00813 static DataStructures::List<unsigned> *_columnIndices;
00814 static DataStructures::List<Table::ColumnDescriptor> *_columns;
00815 int RowSort(Table::Row* const &first, Table::Row* const &second) // first is the one inserting, second is the one already there.
00816 {
00817         unsigned i, columnIndex;
00818         for (i=0; i<_numSortQueries; i++)
00819         {
00820                 columnIndex=(*_columnIndices)[i];
00821                 if (columnIndex==(unsigned)-1)
00822                         continue;
00823 
00824                 if (first->cells[columnIndex]->isEmpty==true && second->cells[columnIndex]->isEmpty==false)
00825                         return 1; // Empty cells always go at the end
00826 
00827                 if (first->cells[columnIndex]->isEmpty==false && second->cells[columnIndex]->isEmpty==true)
00828                         return -1; // Empty cells always go at the end
00829 
00830                 if (_sortQueries[i].operation==Table::QS_INCREASING_ORDER)
00831                 {
00832                         if ((*_columns)[columnIndex].columnType==Table::NUMERIC)
00833                         {
00834                                 if (first->cells[columnIndex]->i>second->cells[columnIndex]->i)
00835                                         return 1;
00836                                 if (first->cells[columnIndex]->i<second->cells[columnIndex]->i)
00837                                         return -1;
00838                         }
00839                         else
00840                         {
00841                                 // String
00842                                 if (strcmp(first->cells[columnIndex]->c,second->cells[columnIndex]->c)>0)
00843                                         return 1;
00844                                 if (strcmp(first->cells[columnIndex]->c,second->cells[columnIndex]->c)<0)
00845                                         return -1;
00846                         }
00847                 }
00848                 else
00849                 {
00850                         if ((*_columns)[columnIndex].columnType==Table::NUMERIC)
00851                         {
00852                                 if (first->cells[columnIndex]->i<second->cells[columnIndex]->i)
00853                                         return 1;
00854                                 if (first->cells[columnIndex]->i>second->cells[columnIndex]->i)
00855                                         return -1;
00856                         }
00857                         else
00858                         {
00859                                 // String
00860                                 if (strcmp(first->cells[columnIndex]->c,second->cells[columnIndex]->c)<0)
00861                                         return 1;
00862                                 if (strcmp(first->cells[columnIndex]->c,second->cells[columnIndex]->c)>0)
00863                                         return -1;
00864                         }
00865                 }
00866         }
00867 
00868         return 0;
00869 }
00870 void Table::SortTable(Table::SortQuery *sortQueries, unsigned numSortQueries, Table::Row** out)
00871 {
00872         unsigned i;
00873         unsigned outLength;
00874         DataStructures::List<unsigned> columnIndices;
00875         _sortQueries=sortQueries;
00876         _numSortQueries=numSortQueries;
00877         _columnIndices=&columnIndices;
00878         _columns=&columns;
00879         bool anyValid=false;
00880 
00881         for (i=0; i < numSortQueries; i++)
00882         {
00883                 if (sortQueries[i].columnIndex<columns.Size() && columns[sortQueries[i].columnIndex].columnType!=BINARY)
00884                 {
00885                         columnIndices.Insert(sortQueries[i].columnIndex, __FILE__, __LINE__);
00886                         anyValid=true;
00887                 }
00888                 else
00889                         columnIndices.Insert((unsigned)-1, __FILE__, __LINE__); // Means don't check this column
00890         }
00891 
00892         DataStructures::Page<unsigned, Row*, _TABLE_BPLUS_TREE_ORDER> *cur;
00893         cur = rows.GetListHead();
00894         if (anyValid==false)
00895         {
00896                 outLength=0;
00897                 while (cur)
00898                 {
00899                         for (i=0; i < (unsigned)cur->size; i++)
00900                         {
00901                                 out[(outLength)++]=cur->data[i];
00902                         }
00903                         cur=cur->next;
00904                 }
00905                 return;
00906         }
00907 
00908         // Start adding to ordered list.
00909         DataStructures::OrderedList<Row*, Row*, RowSort> orderedList;
00910         while (cur)
00911         {
00912                 for (i=0; i < (unsigned)cur->size; i++)
00913                 {
00914                         RakAssert(cur->data[i]);
00915                         orderedList.Insert(cur->data[i],cur->data[i], true, __FILE__,__LINE__);
00916                 }
00917                 cur=cur->next;
00918         }
00919 
00920         outLength=0;
00921         for (i=0; i < orderedList.Size(); i++)
00922                 out[(outLength)++]=orderedList[i];
00923 }
00924 void Table::PrintColumnHeaders(char *out, int outLength, char columnDelineator) const
00925 {
00926         if (outLength<=0)
00927                 return;
00928         if (outLength==1)
00929         {
00930                 *out=0;
00931                 return;
00932         }
00933 
00934         unsigned i;
00935         out[0]=0;
00936         int len;
00937         for (i=0; i < columns.Size(); i++)
00938         {
00939                 if (i!=0)
00940                 {
00941                         len = (int) strlen(out);
00942                         if (len < outLength-1)
00943                                 sprintf(out+len, "%c", columnDelineator);
00944                         else
00945                                 return;
00946                 }
00947 
00948                 len = (int) strlen(out);
00949                 if (len < outLength-(int) strlen(columns[i].columnName))
00950                         sprintf(out+len, "%s", columns[i].columnName);
00951                 else
00952                         return;
00953         }
00954 }
00955 void Table::PrintRow(char *out, int outLength, char columnDelineator, bool printDelineatorForBinary, Table::Row* inputRow) const
00956 {
00957         if (outLength<=0)
00958                 return;
00959         if (outLength==1)
00960         {
00961                 *out=0;
00962                 return;
00963         }
00964 
00965         if (inputRow->cells.Size()!=columns.Size())
00966         {
00967                 strncpy(out, "Cell width does not match column width.\n", outLength);
00968                 out[outLength-1]=0;
00969                 return;
00970         }
00971 
00972         char buff[512];
00973         unsigned i;
00974         int len;
00975         out[0]=0;
00976         for (i=0; i < columns.Size(); i++)
00977         {
00978         if (columns[i].columnType==NUMERIC)
00979                 {
00980                         if (inputRow->cells[i]->isEmpty==false)
00981                         {
00982                                 sprintf(buff, "%f", inputRow->cells[i]->i);
00983                                 len=(int)strlen(buff);
00984                         }
00985                         else
00986                                 len=0;
00987                         if (i+1!=columns.Size())
00988                                 buff[len++]=columnDelineator;
00989                         buff[len]=0;
00990                 }
00991                 else if (columns[i].columnType==STRING)
00992                 {
00993                         if (inputRow->cells[i]->isEmpty==false && inputRow->cells[i]->c)
00994                         {
00995                                 strncpy(buff, inputRow->cells[i]->c, 512-2);
00996                                 buff[512-2]=0;
00997                                 len=(int)strlen(buff);
00998                         }
00999                         else
01000                                 len=0;
01001                         if (i+1!=columns.Size())
01002                                 buff[len++]=columnDelineator;
01003                         buff[len]=0;
01004                 }
01005                 else if (columns[i].columnType==POINTER)
01006                 {
01007                         if (inputRow->cells[i]->isEmpty==false && inputRow->cells[i]->ptr)
01008                         {
01009                                 sprintf(buff, "%p", inputRow->cells[i]->ptr);
01010                                 len=(int)strlen(buff);
01011                         }
01012                         else
01013                                 len=0;
01014                         if (i+1!=columns.Size())
01015                                 buff[len++]=columnDelineator;
01016                         buff[len]=0;
01017                 }
01018                 else
01019                 {
01020                         if (printDelineatorForBinary)
01021                         {
01022                                 if (i+1!=columns.Size())
01023                                         buff[0]=columnDelineator;
01024                                 buff[1]=0;
01025                         }
01026                         else
01027                                 buff[0]=0;
01028 
01029                 }
01030 
01031                 len=(int)strlen(out);
01032                 if (outLength==len+1)
01033                         break;
01034                 strncpy(out+len, buff, outLength-len);
01035                 out[outLength-1]=0;
01036         }
01037 }
01038 
01039 void Table::Clear(void)
01040 {
01041         rows.ForEachData(FreeRow);
01042         rows.Clear();
01043         columns.Clear(true, __FILE__, __LINE__);
01044 }
01045 const List<Table::ColumnDescriptor>& Table::GetColumns(void) const
01046 {
01047         return columns;
01048 }
01049 const DataStructures::BPlusTree<unsigned, Table::Row*, _TABLE_BPLUS_TREE_ORDER>& Table::GetRows(void) const
01050 {
01051         return rows;
01052 }
01053 DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> * Table::GetListHead(void)
01054 {
01055         return rows.GetListHead();
01056 }
01057 unsigned Table::GetAvailableRowId(void) const
01058 {
01059         bool setKey=false;
01060         unsigned key=0;
01061         int i;
01062         DataStructures::Page<unsigned, Row*, _TABLE_BPLUS_TREE_ORDER> *cur = rows.GetListHead();
01063         
01064         while (cur)
01065         {
01066                 for (i=0; i < cur->size; i++)
01067                 {
01068                         if (setKey==false)
01069                         {
01070                                 key=cur->keys[i]+1;
01071                                 setKey=true;
01072                         }
01073                         else
01074                         {
01075                                 if (key!=cur->keys[i])
01076                                         return key;
01077                                 key++;
01078                         }
01079                 }
01080 
01081                 cur=cur->next;
01082         }
01083         return key;
01084 }
01085 void Table::DeleteRow(Table::Row *row)
01086 {
01087         unsigned rowIndex;
01088         for (rowIndex=0; rowIndex < row->cells.Size(); rowIndex++)
01089         {
01090                 RakNet::OP_DELETE(row->cells[rowIndex], __FILE__, __LINE__);
01091         }
01092         RakNet::OP_DELETE(row, __FILE__, __LINE__);
01093 }
01094 Table& Table::operator = ( const Table& input )
01095 {
01096         Clear();
01097 
01098         unsigned int i;
01099         for (i=0; i < input.GetColumnCount(); i++)
01100                 AddColumn(input.ColumnName(i), input.GetColumnType(i));
01101 
01102         DataStructures::Page<unsigned, Row*, _TABLE_BPLUS_TREE_ORDER> *cur = input.GetRows().GetListHead();
01103         while (cur)
01104         {
01105                 for (i=0; i < (unsigned int) cur->size; i++)
01106                 {
01107                         AddRow(cur->keys[i], cur->data[i]->cells, false);
01108                 }
01109 
01110                 cur=cur->next;
01111         }
01112 
01113         return *this;
01114 }
01115 
01116 #ifdef _MSC_VER
01117 #pragma warning( pop )
01118 #endif

Generated on Thu Sep 30 2010 01:27:23 for RakNet by  doxygen 1.7.1