#include "LightweightDatabaseServer.h"
#include "LightweightDatabaseClient.h"
#include "TableSerializer.h"
#include "BitStream.h"
#include "StringCompressor.h"
#include "DS_Table.h"
#include "LightweightDatabaseClient.h"
#include "LightweightDatabaseServer.h"
#include "RakPeerInterface.h"
#include "RakNetworkFactory.h"
#include "RakSleep.h"
#include "PacketEnumerations.h"
#include <conio.h>
#include <stdlib.h>
void main(void)
{
char ch;
bool isServer;
LightweightDatabaseServer databaseServer;
LightweightDatabaseClient databaseClient;
RakPeerInterface *rakPeer = RakNetworkFactory::GetRakPeerInterface();
char str[256];
char columnName[256];
char tableName[256], tablePassword[256];
printf("(S)erver or (C)lient?\n");
ch=getch();
if (ch=='s')
{
isServer=true;
rakPeer->SetMaximumIncomingConnections(32);
rakPeer->Initialize(32, 12345, 0, 0 );
rakPeer->AttachPlugin(&databaseServer);
printf("Server started\n");
printf("(C)reate table\n");
printf("(R)emove table\n");
}
else
{
isServer=false;
rakPeer->Initialize(1, 0, 0, 0);
rakPeer->AttachPlugin(&databaseClient);
printf("Client started\n");
printf("Enter server IP: ");
gets(str);
if (str[0]==0)
strcpy(str, "127.0.0.1");
printf("Connecting to server.\n");
rakPeer->Connect(str, 12345, 0, 0);
printf("(Q)uery table\n");
printf("(U)pdate row\n");
printf("(R)emove row\n");
}
printf("(E)xit\n");
Packet *p;
while (1)
{
p=rakPeer->Receive();
while (p)
{
if (p->data[0]==ID_DISCONNECTION_NOTIFICATION)
printf("ID_DISCONNECTION_NOTIFICATION\n");
else if (p->data[0]==ID_CONNECTION_LOST)
printf("ID_CONNECTION_LOST\n");
else if (p->data[0]==ID_NO_FREE_INCOMING_CONNECTIONS)
printf("ID_NO_FREE_INCOMING_CONNECTIONS\n");
else if (p->data[0]==ID_NEW_INCOMING_CONNECTION)
printf("ID_NEW_INCOMING_CONNECTION\n");
else if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED)
printf("ID_CONNECTION_REQUEST_ACCEPTED\n");
else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED)
printf("ID_CONNECTION_ATTEMPT_FAILED\n");
else if (p->data[0]==ID_DATABASE_UNKNOWN_TABLE)
printf("ID_DATABASE_UNKNOWN_TABLE\n");
else if (p->data[0]==ID_DATABASE_INCORRECT_PASSWORD)
printf("ID_DATABASE_INCORRECT_PASSWORD\n");
else if (p->data[0]==ID_DATABASE_QUERY_REPLY)
{
printf("Incoming table:\n");
DataStructures::Table table;
if (TableSerializer::DeserializeTable(p->data+sizeof(MessageID), p->length-sizeof(MessageID), &table))
{
DataStructures::Page<unsigned, DataStructures::Table::Row*, _TABLE_BPLUS_TREE_ORDER> *cur = table.GetListHead();
unsigned i;
printf("Columns:\n");
for (i=0; i < table.GetColumns().Size(); i++)
{
printf("%i. %s : ", i+1, table.GetColumns()[i].columnName);
if (table.GetColumns()[i].columnType==DataStructures::Table::ColumnType::BINARY)
printf("BINARY");
else if (table.GetColumns()[i].columnType==DataStructures::Table::ColumnType::NUMERIC)
printf("NUMERIC");
else
printf("STRING");
printf("\n");
}
if (cur)
printf("Rows:\n");
else
printf("Table has no rows.\n");
while (cur)
{
for (i=0; i < (unsigned)cur->size; i++)
{
table.PrintRow(str, 256, ',', true, cur->data[i]);
printf("RowID %i: %s\n", cur->keys[i], str );
}
cur=cur->next;
}
}
else
printf("Deserialization of table failed.\n");
}
rakPeer->DeallocatePacket(p);
p=rakPeer->Receive();
}
if (kbhit())
{
char ch=getch();
if (isServer)
{
if (ch=='c')
{
bool allowRemoteUpdate;
bool allowRemoteQuery;
bool allowRemoteRemove;
char queryPassword[_SIMPLE_DATABASE_PASSWORD_LENGTH];
char updatePassword[_SIMPLE_DATABASE_PASSWORD_LENGTH];
char removePassword[_SIMPLE_DATABASE_PASSWORD_LENGTH];
bool oneRowPerSystemId;
bool onlyUpdateOwnRows;
bool removeRowOnPingFailure;
bool removeRowOnDisconnect;
bool autogenerateRowIDs;
printf("Enter name of table to create: ");
gets(tableName);
if (tableName[0]==0)
strcpy(tableName, "Default Table");
printf("Allow remote row updates? (y (Default) / n)\n");
if (getche()=='n')
{
printf("\n");
allowRemoteUpdate=false;
}
else
{
printf("\n");
allowRemoteUpdate=true;
printf("Enter remote update password (Enter for none): ");
gets(updatePassword);
printf("Only allow one row per uploading IP? (y (Default) / n)\n");
oneRowPerSystemId = (getche()=='n')==false;
printf("Only allow updates on rows created by that system? (y (Default) / n)\n");
onlyUpdateOwnRows = (getche()=='n')==false;
printf("Remove row if can't ping system? (y (Default) / n)\n");
removeRowOnPingFailure = (getche()=='n')==false;
printf("Remove row on system disconnect? (y / n (Default))\n");
removeRowOnDisconnect = (getche()=='y')==true;
}
printf("Allow remote table queries? (y (Default) / n)\n");
if (getche()=='n')
{
printf("\n");
allowRemoteQuery=false;
}
else
{
printf("\n");
allowRemoteQuery=true;
printf("Enter remote table query password (Enter for none): ");
gets(queryPassword);
}
printf("Allow remote row removal? (y (Default) / n)\n");
if (getche()=='n')
{
printf("\n");
allowRemoteRemove=false;
}
else
{
printf("\n");
allowRemoteRemove=true;
printf("Enter remote row removal password (Enter for none): ");
gets(removePassword);
}
printf("Autogenerate row ids? (y (Default) / n)\n");
autogenerateRowIDs = (getche()=='n')==false;
DataStructures::Table *table;
table=databaseServer.AddTable(tableName, allowRemoteUpdate, allowRemoteQuery, allowRemoteRemove, queryPassword, updatePassword, removePassword, oneRowPerSystemId, onlyUpdateOwnRows, removeRowOnPingFailure, removeRowOnDisconnect, autogenerateRowIDs);
if (table)
{
printf("Table %s created.\n", tableName);
while (1)
{
printf("Enter name of new column\n");
printf("Hit enter when done\n");
gets(columnName);
if (columnName[0]==0)
break;
DataStructures::Table::ColumnType columnType;
printf("Enter column type\n1=STRING\n2=NUMERIC\n3=BINARY\n");
gets(str);
if (str[0]=='1')
columnType=DataStructures::Table::ColumnType::STRING;
else if (str[0]=='2')
columnType=DataStructures::Table::ColumnType::NUMERIC;
else if (str[0]=='3')
columnType=DataStructures::Table::ColumnType::BINARY;
else
{
printf("Defaulting to string\n");
columnType=DataStructures::Table::ColumnType::STRING;
}
table->AddColumn(columnName, columnType);
printf("%s added.\n", columnName);
}
printf("Done.\n");
}
else
printf("Table %s creation failed. Possibly already exists.\n", tableName);
}
else if (ch=='r')
{
printf("Enter name of table to remove: ");
gets(str);
if (str[0]==0)
strcpy(str, "Default Table");
if (databaseServer.RemoveTable(str))
printf("Success\n");
else
printf("Table %s not found\n", str);
}
}
else
{
if (ch=='q' || ch=='u' || ch=='r')
{
printf("Enter table name: ");
gets(tableName);
if (tableName[0]==0)
strcpy(tableName, "Default Table");
printf("Enter password (if any): ");
gets(tablePassword);
}
if (ch=='q')
{
// TODO - let the user enter filters, columns, and rows to return.
databaseClient.QueryTable(tableName, tablePassword, 0, 0, 0, 0, 0, 0, UNASSIGNED_PLAYER_ID, true);
}
else if (ch=='u')
{
RowUpdateMode updateMode;
unsigned rowId;
bool hasRowId;
printf("Enter row update mode\n1=update existing\n2=update or add\n3=add new\n");
gets(str);
if (str[0]=='1')
{
updateMode=RUM_UPDATE_EXISTING_ROW;
printf("Updating existing row (You must enter a row ID).\n");
}
else if (str[0]=='2')
{
updateMode=RUM_UPDATE_OR_ADD_ROW;
printf("Updating existing row and adding\nnew row if existing row does not exist.\n");
}
else
{
updateMode=RUM_ADD_NEW_ROW;
printf("Adding new row.\n");
}
printf("Enter row ID (enter for none): ");
gets(str);
if (str[0])
{
rowId=atoi(str);
hasRowId=true;
}
else
{
hasRowId=false;
rowId=0;
}
printf("Enter cells\n");
unsigned char numCellUpdates;
DatabaseCellUpdate cellUpdates[64];
for (numCellUpdates=0; numCellUpdates<64; numCellUpdates++)
{
printf("Enter column name (Enter when done): ");
gets(cellUpdates[numCellUpdates].columnName);
if (cellUpdates[numCellUpdates].columnName[0]==0)
break;
printf("Enter column type\n1=STRING\n2=NUMERIC\n3=BINARY\n");
gets(str);
if (str[0]=='1' || str[0]==0)
{
cellUpdates[numCellUpdates].columnType=DataStructures::Table::ColumnType::STRING;
printf("Enter string value: ");
gets(str);
cellUpdates[numCellUpdates].cellValue.Set(str);
}
else if (str[0]=='2')
{
cellUpdates[numCellUpdates].columnType=DataStructures::Table::ColumnType::NUMERIC;
printf("Enter numeric value: ");
gets(str);
cellUpdates[numCellUpdates].cellValue.Set(atoi(str));
}
else
{
cellUpdates[numCellUpdates].columnType=DataStructures::Table::ColumnType::BINARY;
// TODO - Pain in the ass to write this demo code
printf("TODO\n");
}
}
databaseClient.UpdateRow(tableName, tablePassword, updateMode, hasRowId, rowId, cellUpdates, numCellUpdates, UNASSIGNED_PLAYER_ID, true );
}
else if (ch=='r')
{
unsigned rowId;
printf("Enter row ID to remove: ");
gets(str);
rowId=atoi(str);
databaseClient.RemoveRow(tableName, tablePassword, rowId, UNASSIGNED_PLAYER_ID, true);
}
}
if (ch=='e')
break;
ch=0;
}
RakSleep(30);
}
rakPeer->Disconnect(100,0);
RakNetworkFactory::DestroyRakPeerInterface(rakPeer);
}
syntax highlighted by Code2HTML, v. 0.9.1