void testStore(void) { // setup struct Command* createDatabaseCommand = createCreateDatabaseCommand("test_store"); createDatabase(createDatabaseCommand); char names[FIELD_SIZE][NAME_LIMIT] = { "name1", "name2", "name3", "name4", }; char values[FIELD_SIZE][VALUE_LIMIT] = { "1", "value2", "1/1/2015", "3", }; FieldType types[FIELD_SIZE][1] = { INTEGER, TEXT, DATE, INTEGER, }; struct Field* fields = createFieldList(names, values, types, 4); struct Command* createTableCmd = createCreateTableCommand("table", fields); createTable(createTableCmd); // test struct Command* insertCmd = createInsertCommand("table", fields); insertTuple(insertCmd); values[0][0] = '2'; insertTuple(insertCmd); // teardown destroyCommand(createDatabaseCommand); destroyCommand(createTableCmd); }
void testCreateTable(void) { struct Command* createDBCommand = createCreateDatabaseCommand("foo"); createDatabase(createDBCommand); assert(strcmp(currentDatabase, "foo") == 0, "currentDatabase should be set!"); char tableFolderPath[PATH_SIZE]; char names[FIELD_SIZE][NAME_LIMIT] = { "name1", "name2", "name3", "name4", }; char values[FIELD_SIZE][VALUE_LIMIT] = { "1", "value2", "1/1/2015", "3", }; FieldType types[FIELD_SIZE][1] = { INTEGER, TEXT, DATE, INTEGER, }; struct Field* fields = createFieldList(names, values, types, 4); struct Command* createTableCmd = createCreateTableCommand("bar", fields); createTable(createTableCmd); sprintf(tableFolderPath, "%s/foo/bar", DATABASE_DIR); assert(access(tableFolderPath, F_OK) != -1, "Table file was not constructed!"); char fileContents[RECORD_SIZE]; FILE* file = fopen(tableFolderPath, "r"); fgets(fileContents, RECORD_SIZE, file); char* header = "name1[I]|name2[T]|name3[D]|name4[I]\n"; assert(strcmp(fileContents, header) == 0, "Table was not written correctly!"); // cleanup garbage fclose(file); destroyCommand(createDBCommand); destroyCommand(createTableCmd); }
void testDropDB(void) { system("mkdir -p out/databases/test_drop"); struct Command* dropDBCommand = createDropDatabaseCommand("test_drop"); dropDatabase(dropDBCommand); //cleanup destroyCommand(dropDBCommand); }
//drop table needs a pathname from the tabe dir in //databases to the table contained within. void testDropTable() { currentDatabase = "test_drop"; system("mkdir -p out/databases/test_drop"); system("touch out/databases/test_drop/data"); struct Command* dropTblCommand = createDropTableCommand("data"); dropTable(dropTblCommand); //cleanup destroyCommand(dropTblCommand); }
void connectionDestroy(connection *con) { printf("Terminating connection from server end...\n"); printf("Closing socket %d\n", con->tArgs->socketFD); close(con->tArgs->socketFD); free(con->tArgs); destroyCommand(con->cmd); free(con->err); responseDestroy(con->res); free(con->tbl); if (con->data != NULL) { free(con->data); } free(con); }
void readDatalink(void){ struct command* cmd = popCommand(); if ( cmd ) { if (lastCommandSentCode == cmd->cmd){ lastCommandSentCode++; } else{ lastCommandSentCode = cmd->cmd * 100; } switch (cmd->cmd) { case DEBUG_TEST: // Debugging command, writes to debug UART debug((char*) cmd->data); break; //TODO: Add commands here default: break; } destroyCommand( cmd ); } }
/******************************************************************************** * Function name : struct command_s *interpretCommand(char *commandLine) * returns : pointer to a command_s structure containing all command * data, ready to be passed to executeCommand() * commandLine : command line input to tokenise and return in command * structure * * Created by : James Johns * Date created : 10/12/2011 * Description : tokenises commandLine by whitespace. first token is command * utility, followed by arguments * * returns tokens in command_s structure which needs * deallocating when no longer needed. * * NOTES : BUG - arguments of created command may have artifacts at the * end of their string ********************************************************************************/ struct command_s *interpretCommand(char *commandLine) { struct command_s *toRet = malloc(sizeof(struct command_s)); /* temporary argument storage. ready to copy into a perfect sized array later on */ char *tempStore[MAXARGUMENTCOUNT]; unsigned int startOfToken = 0; char *redirectedFileName; if (toRet == NULL) { perror("interpretCommand"); } else { toRet->next = NULL; toRet->backgroundTask = 0; toRet->inputFD = toRet->outputFD = -1; toRet->argc = 0; toRet->argv = malloc(sizeof(char *)*2); if (toRet->argv == NULL) { perror("interpretCommand: malloc"); free(toRet); return NULL; } int i = 0; /* ignore leading whitespace */ while ((i < strlen(commandLine)) && ((commandLine[i] == ' ') || (commandLine[i] == '\n'))) i++; if (i >= strlen(commandLine)) { /* no command to parse, so ignore it and return NULL */ fprintf(stderr, "Empty command detected\n"); free(toRet); toRet = NULL; return NULL; } startOfToken = i; /* could characters in command name, ready to allocate required space. */ for (; i < strlen(commandLine) && commandLine[i] != ' ' && commandLine[i] != '\n'; i++); /* count through characters until we reach the end * of the string or a tokenising character */ toRet->argv[0] = malloc(sizeof(char)*((i-startOfToken)+1)); toRet->argc++; strncpy(toRet->argv[0], &commandLine[startOfToken], i-(startOfToken)); /* startOfToken is an index. add one for calculating length properly */ toRet->argv[0][i-startOfToken] = NULL; toRet->argv[1] = NULL; /* make sure even for single commands, argv[] ends in a NULL pointer */ i++; startOfToken = i; /* loop until we reach the end of the string or we hit a new line character * tokenising the string at each space character */ while (i <= strlen(commandLine)) { switch (commandLine[i]) { case ' ': case '\n': case '\0': /* if 2 separators are found next to eachother, ignore the first separator and * use the second as the startOfToken point. */ if (i == startOfToken) { i++; startOfToken = i; break; } /* create a token from string */ tempStore[toRet->argc] = malloc(sizeof(char)*(i-startOfToken)+1); strncpy(tempStore[toRet->argc],commandLine+startOfToken,i-startOfToken); tempStore[toRet->argc][i-startOfToken] = '\0'; toRet->argc++; /* set records to beginning of the next possible token */ startOfToken = i; break; case '|': toRet->next = interpretCommand(commandLine+i+1); i = strlen(commandLine); break; case '&': /* send child process to background */ toRet->backgroundTask = 1; i++; break; case '>': /* next argument is the file to redirect into. */; i++; while (commandLine[i] == ' ' || commandLine[i] == '\t') i++; startOfToken = i; for (; i < strlen(commandLine) && commandLine != '\0' && commandLine[i] != '\n' && commandLine[i] != ' '; i++); if (i != startOfToken) { int filenameLength = (i-startOfToken); redirectedFileName = malloc(sizeof(char)*filenameLength); strncpy(redirectedFileName, commandLine, filenameLength); redirectedFileName[filenameLength] = '\0'; FILE *outputFile = fopen(redirectedFileName, "w"); if (outputFile == NULL) { perror("fopen"); } else { toRet->outputFD = fileno(outputFile); } } break; default: i++; break; } } /* copy arguments into command structure */ if (toRet->argc > 1) { toRet->argv = realloc(toRet->argv, sizeof(char *)*(toRet->argc+1)); /* loop through tempStore, copying all strings across to argv */ for (int j = 1; j < toRet->argc; j++) { toRet->argv[j] = tempStore[j]; } toRet->argv[toRet->argc] = NULL; } /* check I/O file descriptors and assign pipes as necessary */ if (toRet->outputFD == -1 && toRet->next != NULL) { /* create a pipe, assign to outputFD and next->outputFD */ int newpipe[2]; if (pipe(newpipe) == -1) { perror("interpretCommand: pipe"); destroyCommand(toRet); return NULL; } toRet->outputFD = newpipe[1]; toRet->next->inputFD = newpipe[0]; } else if (toRet->outputFD == -1 && toRet->next == NULL) { /* end of command list, output must be to stdout unless being rediected already. */ toRet->outputFD = fileno(stdout); } if (toRet->inputFD == -1) { /* if input has not been assigned yet, assign standard input to inputFD */ toRet->inputFD = fileno(stdin); } } return toRet; }