Minor fixes
This commit is contained in:
parent
799b10d545
commit
72e61a1025
BIN
database.db
BIN
database.db
Binary file not shown.
61
include/db.h
61
include/db.h
@ -1,42 +1,53 @@
|
||||
#ifndef _DB_H_
|
||||
#define _DB_H_
|
||||
#ifndef DB_H
|
||||
#define DB_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_TABLES 10
|
||||
#define MAX_COLUMNS 10
|
||||
#define MAX_ROWS 100
|
||||
#define MAX_QUERY_LENGTH 256
|
||||
#define MAX_NAME_LENGTH 50
|
||||
|
||||
/* Default filename for saving/loading the database */
|
||||
#define DB_FILE "database.db"
|
||||
|
||||
typedef struct
|
||||
|
||||
typedef struct Column
|
||||
{
|
||||
char name[MAX_NAME_LENGTH];
|
||||
char data[MAX_ROWS][MAX_NAME_LENGTH];
|
||||
char *name;
|
||||
char **data; /* Array of string data for each row */
|
||||
} Column;
|
||||
|
||||
typedef struct
|
||||
typedef struct Table
|
||||
{
|
||||
char name[MAX_NAME_LENGTH];
|
||||
Column columns[MAX_COLUMNS];
|
||||
int column_count;
|
||||
char *name;
|
||||
int row_count;
|
||||
int column_count;
|
||||
Column **columns;
|
||||
} Table;
|
||||
|
||||
typedef struct
|
||||
typedef struct Database
|
||||
{
|
||||
Table tables[MAX_TABLES];
|
||||
int table_count;
|
||||
Table **tables;
|
||||
} Database;
|
||||
|
||||
/* Database Operations */
|
||||
Database *create_db(void);
|
||||
void create_table(Database *db, const char *table_name, char *columns);
|
||||
void insert_into_table(Database *db, const char *table_name, char *values);
|
||||
void select_from_table(Database *db, const char *table_name);
|
||||
void parse_query(Database *db, const char *query);
|
||||
Table *find_table(Database *db, const char *table_name);
|
||||
void save_database_to_file(Database *db, const char *filename);
|
||||
void load_database_from_file(Database *db, const char *filename);
|
||||
int validate_ipv4_address(const char *ip);
|
||||
void trim_whitespace(char *str);
|
||||
void free_database(Database *db);
|
||||
|
||||
#endif
|
||||
/* Table Operations */
|
||||
Table *find_table(Database *db, const char *table_name);
|
||||
void create_table(Database *db, const char *table_name, const char *columns_str);
|
||||
void insert_into_table(Database *db, const char *table_name, const char *values_str);
|
||||
void select_from_table(Database *db, const char *table_name);
|
||||
|
||||
/* File Operations */
|
||||
void save_database_to_file(Database *db, const char *filename);
|
||||
Database *load_database_from_file(Database *db, const char *filename);
|
||||
|
||||
/* Query Parsing */
|
||||
Database *parse_query(Database *db, const char *query);
|
||||
|
||||
/* Utility Functions */
|
||||
int validate_ipv4_address(const char *ip);
|
||||
char *trim_whitespace(char *str);
|
||||
|
||||
#endif /* DB_H */
|
||||
|
487
src/db.c
487
src/db.c
@ -2,42 +2,79 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "db.h"
|
||||
|
||||
void trim_whitespace(char *str)
|
||||
/* Writes a string to a file.
|
||||
* The string is preceded by its length (including the null terminator).
|
||||
*/
|
||||
static void write_string(FILE *file, const char *str)
|
||||
{
|
||||
int len = (int)strlen(str) + 1;
|
||||
fwrite(&len, sizeof(int), 1, file);
|
||||
fwrite(str, sizeof(char), len, file);
|
||||
}
|
||||
|
||||
/* Reads a string from a file that was written using write_string.
|
||||
* Returns a pointer to the heap-allocated string, or NULL on failure.
|
||||
*/
|
||||
static char *read_string(FILE *file)
|
||||
{
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
if (fread(&len, sizeof(int), 1, file) != 1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str = malloc(len);
|
||||
if (str == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fread(str, sizeof(char), len, file);
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Trims leading and trailing whitespace from a string in place.
|
||||
* Returns a pointer to the trimmed string.
|
||||
*/
|
||||
char *trim_whitespace(char *str)
|
||||
{
|
||||
char *end;
|
||||
|
||||
/* Trim leading whitespace */
|
||||
while (isspace((unsigned char)*str))
|
||||
{
|
||||
str++;
|
||||
}
|
||||
|
||||
if (*str == 0)
|
||||
if (*str == '\0')
|
||||
{
|
||||
return;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Trim trailing whitespace */
|
||||
end = str + strlen(str) - 1;
|
||||
|
||||
while (end > str && isspace((unsigned char)*end))
|
||||
{
|
||||
end--;
|
||||
}
|
||||
|
||||
/* Write new null terminator */
|
||||
end[1] = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Validates if the provided string is in valid IPv4 format.
|
||||
* Returns 1 if valid, 0 otherwise.
|
||||
*/
|
||||
int validate_ipv4_address(const char *ip)
|
||||
{
|
||||
int segments;
|
||||
int ch_count;
|
||||
const char *ptr;
|
||||
|
||||
segments = 0;
|
||||
ch_count = 0;
|
||||
ptr = ip;
|
||||
int segments = 0;
|
||||
int ch_count = 0;
|
||||
const char *ptr = ip;
|
||||
|
||||
while (*ptr)
|
||||
{
|
||||
@ -47,7 +84,6 @@ int validate_ipv4_address(const char *ip)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
segments++;
|
||||
ch_count = 0;
|
||||
}
|
||||
@ -59,7 +95,6 @@ int validate_ipv4_address(const char *ip)
|
||||
{
|
||||
ch_count++;
|
||||
}
|
||||
|
||||
ptr++;
|
||||
}
|
||||
|
||||
@ -67,217 +102,389 @@ int validate_ipv4_address(const char *ip)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Creates a new Database instance.
|
||||
* Returns a pointer to the new Database or NULL on failure.
|
||||
*/
|
||||
Database *create_db(void)
|
||||
{
|
||||
Database *db;
|
||||
|
||||
db = calloc(1, sizeof(*db));
|
||||
Database *db = malloc(sizeof(Database));
|
||||
if (db == NULL)
|
||||
{
|
||||
printf("Failed to allocate memory for DB.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
db->tables = NULL;
|
||||
db->table_count = 0;
|
||||
return db;
|
||||
}
|
||||
|
||||
Table *find_table(Database *db, const char *table_name)
|
||||
/* Frees all memory associated with the Database.
|
||||
*/
|
||||
void free_database(Database *db)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < db->table_count; i++)
|
||||
if (db == NULL)
|
||||
{
|
||||
if (strcmp(db->tables[i].name, table_name) == 0)
|
||||
{
|
||||
return &db->tables[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void create_table(Database *db, const char *table_name, char *columns)
|
||||
{
|
||||
Table *table;
|
||||
char *token;
|
||||
|
||||
if (db->table_count >= MAX_TABLES)
|
||||
{
|
||||
printf("Error: Maximum table limit reached.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (find_table(db, table_name))
|
||||
for (int i = 0; i < db->table_count; i++)
|
||||
{
|
||||
Table *currTable = db->tables[i];
|
||||
free(currTable->name);
|
||||
|
||||
for (int j = 0; j < currTable->column_count; j++)
|
||||
{
|
||||
Column *currColumn = currTable->columns[j];
|
||||
free(currColumn->name);
|
||||
|
||||
for (int r = 0; r < currTable->row_count; r++)
|
||||
{
|
||||
free(currColumn->data[r]);
|
||||
}
|
||||
free(currColumn->data);
|
||||
free(currColumn);
|
||||
}
|
||||
free(currTable->columns);
|
||||
free(currTable);
|
||||
}
|
||||
free(db->tables);
|
||||
free(db);
|
||||
}
|
||||
|
||||
/* Searches for a table by name in the Database.
|
||||
* Returns a pointer to the Table if found, or NULL otherwise.
|
||||
*/
|
||||
Table *find_table(Database *db, const char *table_name)
|
||||
{
|
||||
for (int i = 0; i < db->table_count; i++)
|
||||
{
|
||||
if (strcmp(db->tables[i]->name, table_name) == 0)
|
||||
{
|
||||
return db->tables[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Creates a new table with the given name and comma-separated column definitions.
|
||||
*/
|
||||
void create_table(Database *db, const char *table_name, const char *columns_str)
|
||||
{
|
||||
if (find_table(db, table_name) != NULL)
|
||||
{
|
||||
printf("Error: Table '%s' already exists.\n", table_name);
|
||||
return;
|
||||
}
|
||||
|
||||
table = &db->tables[db->table_count++];
|
||||
strcpy(table->name, table_name);
|
||||
table->column_count = 0;
|
||||
table->row_count = 0;
|
||||
|
||||
token = strtok(columns, ",");
|
||||
|
||||
while (token && table->column_count < MAX_COLUMNS)
|
||||
Table *table = malloc(sizeof(Table));
|
||||
if (table == NULL)
|
||||
{
|
||||
trim_whitespace(token);
|
||||
strcpy(table->columns[table->column_count++].name, token);
|
||||
printf("Error: Memory allocation failed for table '%s'.\n", table_name);
|
||||
return;
|
||||
}
|
||||
table->name = strdup(table_name);
|
||||
table->row_count = 0;
|
||||
table->column_count = 0;
|
||||
table->columns = NULL;
|
||||
|
||||
char *cols_copy = strdup(columns_str);
|
||||
if (cols_copy == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed for columns copy.\n");
|
||||
free(table);
|
||||
return;
|
||||
}
|
||||
|
||||
char *token = strtok(cols_copy, ",");
|
||||
while (token != NULL)
|
||||
{
|
||||
token = trim_whitespace(token);
|
||||
Column *col = malloc(sizeof(Column));
|
||||
if (col == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed for column '%s'.\n", token);
|
||||
free(cols_copy);
|
||||
return;
|
||||
}
|
||||
col->name = strdup(token);
|
||||
col->data = NULL;
|
||||
|
||||
table->columns = realloc(table->columns, sizeof(Column*) * (table->column_count + 1));
|
||||
if (table->columns == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed while adding column '%s'.\n", token);
|
||||
free(col->name);
|
||||
free(col);
|
||||
free(cols_copy);
|
||||
return;
|
||||
}
|
||||
table->columns[table->column_count++] = col;
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
free(cols_copy);
|
||||
|
||||
if (table->column_count == 0)
|
||||
{
|
||||
printf("Error: No columns defined for table '%s'.\n", table_name);
|
||||
db->table_count--;
|
||||
free(table->name);
|
||||
free(table);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Table '%s' with %d columns created successfully.\n", table_name, table->column_count);
|
||||
db->tables = realloc(db->tables, sizeof(Table*) * (db->table_count + 1));
|
||||
if (db->tables == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed while adding table '%s'.\n", table_name);
|
||||
free_database(db);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
db->tables[db->table_count++] = table;
|
||||
|
||||
printf("Table '%s' with %d columns created successfully.\n", table->name, table->column_count);
|
||||
}
|
||||
|
||||
void insert_into_table(Database *db, const char *table_name, char *values)
|
||||
/* Inserts a new row into the specified table using comma-separated values.
|
||||
*/
|
||||
void insert_into_table(Database *db, const char *table_name, const char *values_str)
|
||||
{
|
||||
Table *table;
|
||||
char *token;
|
||||
int col_index;
|
||||
|
||||
table = find_table(db, table_name);
|
||||
|
||||
if (!table)
|
||||
Table *table = find_table(db, table_name);
|
||||
if (table == NULL)
|
||||
{
|
||||
printf("Error: Table '%s' does not exist.\n", table_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (table->column_count == 0)
|
||||
char *vals_copy = strdup(values_str);
|
||||
if (vals_copy == NULL)
|
||||
{
|
||||
printf("Error: Table '%s' has no columns defined.\n", table_name);
|
||||
printf("Error: Memory allocation failed for values copy.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (table->row_count >= MAX_ROWS)
|
||||
char *token = strtok(vals_copy, ",");
|
||||
int col_index = 0;
|
||||
char **values = malloc(sizeof(char*) * table->column_count);
|
||||
if (values == NULL)
|
||||
{
|
||||
printf("Error: Maximum row limit reached for table '%s'.\n", table_name);
|
||||
printf("Error: Memory allocation failed for values array.\n");
|
||||
free(vals_copy);
|
||||
return;
|
||||
}
|
||||
|
||||
token = strtok(values, ",");
|
||||
col_index = 0;
|
||||
|
||||
while (token && col_index < table->column_count)
|
||||
while (token != NULL && col_index < table->column_count)
|
||||
{
|
||||
trim_whitespace(token);
|
||||
|
||||
if (strcmp(table->columns[col_index].name, "IPv4") == 0)
|
||||
token = trim_whitespace(token);
|
||||
/* Validate IPv4 address if required */
|
||||
if (strcmp(table->columns[col_index]->name, "IPv4") == 0)
|
||||
{
|
||||
if (!validate_ipv4_address(token))
|
||||
{
|
||||
printf("Error: Invalid IPv4 address '%s'.\n", token);
|
||||
free(vals_copy);
|
||||
for (int i = 0; i < col_index; i++)
|
||||
{
|
||||
free(values[i]);
|
||||
}
|
||||
free(values);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(table->columns[col_index].data[table->row_count], token);
|
||||
values[col_index++] = strdup(token);
|
||||
token = strtok(NULL, ",");
|
||||
col_index++;
|
||||
}
|
||||
free(vals_copy);
|
||||
|
||||
if (col_index != table->column_count)
|
||||
{
|
||||
printf("Error: Column count mismatch for table '%s'.\n", table_name);
|
||||
for (int i = 0; i < col_index; i++)
|
||||
{
|
||||
free(values[i]);
|
||||
}
|
||||
free(values);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < table->column_count; i++)
|
||||
{
|
||||
Column *col = table->columns[i];
|
||||
col->data = realloc(col->data, sizeof(char*) * (table->row_count + 1));
|
||||
if (col->data == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed while inserting row.\n");
|
||||
free(values);
|
||||
return;
|
||||
}
|
||||
col->data[table->row_count] = values[i];
|
||||
}
|
||||
free(values);
|
||||
table->row_count++;
|
||||
printf("Row inserted into table '%s'.\n", table_name);
|
||||
}
|
||||
|
||||
/* Displays the contents of the specified table.
|
||||
*/
|
||||
void select_from_table(Database *db, const char *table_name)
|
||||
{
|
||||
Table *table;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
table = find_table(db, table_name);
|
||||
|
||||
if (!table)
|
||||
Table *table = find_table(db, table_name);
|
||||
if (table == NULL)
|
||||
{
|
||||
printf("Error: Table '%s' does not exist.\n", table_name);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Table: %s\n", table->name);
|
||||
|
||||
for (i = 0; i < table->column_count; i++)
|
||||
for (int i = 0; i < table->column_count; i++)
|
||||
{
|
||||
printf("%s\t", table->columns[i].name);
|
||||
printf("%s\t", table->columns[i]->name);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
for (i = 0; i < table->row_count; i++)
|
||||
for (int r = 0; r < table->row_count; r++)
|
||||
{
|
||||
for (j = 0; j < table->column_count; j++)
|
||||
for (int c = 0; c < table->column_count; c++)
|
||||
{
|
||||
printf("%s\t", table->columns[j].data[i]);
|
||||
printf("%s\t", table->columns[c]->data[r]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Saves the database to a binary file.
|
||||
*/
|
||||
void save_database_to_file(Database *db, const char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
file = fopen(filename, "wb");
|
||||
|
||||
if (!file)
|
||||
FILE *file = fopen(filename, "wb");
|
||||
if (file == NULL)
|
||||
{
|
||||
printf("Error: Could not open file '%s' for writing.\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
fwrite(db, sizeof(Database), 1, file);
|
||||
fwrite(&db->table_count, sizeof(int), 1, file);
|
||||
for (int i = 0; i < db->table_count; i++)
|
||||
{
|
||||
Table *table = db->tables[i];
|
||||
write_string(file, table->name);
|
||||
fwrite(&table->column_count, sizeof(int), 1, file);
|
||||
fwrite(&table->row_count, sizeof(int), 1, file);
|
||||
|
||||
for (int j = 0; j < table->column_count; j++)
|
||||
{
|
||||
Column *col = table->columns[j];
|
||||
write_string(file, col->name);
|
||||
for (int r = 0; r < table->row_count; r++)
|
||||
{
|
||||
write_string(file, col->data[r]);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
printf("Database saved to '%s'.\n", filename);
|
||||
}
|
||||
|
||||
void load_database_from_file(Database *db, const char *filename)
|
||||
/* Loads a database from a binary file.
|
||||
* Frees the current database and returns a new one loaded from the file.
|
||||
*/
|
||||
Database *load_database_from_file(Database *db, const char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
|
||||
file = fopen(filename, "rb");
|
||||
|
||||
if (!file)
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if (file == NULL)
|
||||
{
|
||||
printf("Error: Could not open file '%s' for reading.\n", filename);
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
fread(db, sizeof(Database), 1, file);
|
||||
free_database(db);
|
||||
Database *new_db = create_db();
|
||||
if (new_db == NULL)
|
||||
{
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int table_count = 0;
|
||||
fread(&table_count, sizeof(int), 1, file);
|
||||
for (int i = 0; i < table_count; i++)
|
||||
{
|
||||
Table *table = malloc(sizeof(Table));
|
||||
if (table == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed while loading table.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
table->name = read_string(file);
|
||||
fread(&table->column_count, sizeof(int), 1, file);
|
||||
fread(&table->row_count, sizeof(int), 1, file);
|
||||
table->columns = NULL;
|
||||
|
||||
for (int j = 0; j < table->column_count; j++)
|
||||
{
|
||||
Column *col = malloc(sizeof(Column));
|
||||
if (col == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed while loading column.\n");
|
||||
continue;
|
||||
}
|
||||
col->name = read_string(file);
|
||||
col->data = NULL;
|
||||
|
||||
for (int r = 0; r < table->row_count; r++)
|
||||
{
|
||||
char *cell = read_string(file);
|
||||
col->data = realloc(col->data, sizeof(char*) * (r + 1));
|
||||
if (col->data == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed while loading row data.\n");
|
||||
free(cell);
|
||||
continue;
|
||||
}
|
||||
col->data[r] = cell;
|
||||
}
|
||||
table->columns = realloc(table->columns, sizeof(Column*) * (j + 1));
|
||||
if (table->columns == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed while loading columns array.\n");
|
||||
free(col);
|
||||
continue;
|
||||
}
|
||||
table->columns[j] = col;
|
||||
}
|
||||
new_db->tables = realloc(new_db->tables, sizeof(Table*) * (i + 1));
|
||||
if (new_db->tables == NULL)
|
||||
{
|
||||
printf("Error: Memory allocation failed while adding table to database.\n");
|
||||
free(table);
|
||||
continue;
|
||||
}
|
||||
new_db->tables[i] = table;
|
||||
new_db->table_count++;
|
||||
}
|
||||
fclose(file);
|
||||
printf("Database loaded from '%s'.\n", filename);
|
||||
return new_db;
|
||||
}
|
||||
|
||||
void parse_query(Database *db, const char *query)
|
||||
/* Parses and executes a query string.
|
||||
* Supported commands: CREATE TABLE, INSERT INTO, SELECT, SAVE, LOAD.
|
||||
*/
|
||||
Database *parse_query(Database *db, const char *query)
|
||||
{
|
||||
char query_copy[MAX_QUERY_LENGTH];
|
||||
char *command;
|
||||
char *table_name;
|
||||
char *columns;
|
||||
strncpy(query_copy, query, MAX_QUERY_LENGTH - 1);
|
||||
query_copy[MAX_QUERY_LENGTH - 1] = '\0';
|
||||
|
||||
strcpy(query_copy, query);
|
||||
command = strtok(query_copy, " ");
|
||||
char *command = strtok(query_copy, " ");
|
||||
if (command == NULL)
|
||||
{
|
||||
printf("Error: Empty query.\n");
|
||||
return db;
|
||||
}
|
||||
|
||||
if (strcmp(command, "CREATE") == 0)
|
||||
{
|
||||
@ -285,40 +492,37 @@ void parse_query(Database *db, const char *query)
|
||||
if (next_token == NULL || strcmp(next_token, "TABLE") != 0)
|
||||
{
|
||||
printf("Error: Invalid CREATE TABLE syntax.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
table_name = strtok(NULL, " ");
|
||||
char *table_name = strtok(NULL, " ");
|
||||
if (table_name == NULL)
|
||||
{
|
||||
printf("Error: Table name is missing.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
columns = strchr(query, '(');
|
||||
char *columns = strchr(query, '(');
|
||||
if (columns == NULL)
|
||||
{
|
||||
printf("Error: Missing column definitions.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
columns++;
|
||||
char *closing_paren = strchr(columns, ')');
|
||||
if (closing_paren == NULL)
|
||||
{
|
||||
printf("Error: Missing closing parenthesis in column definitions.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
*closing_paren = '\0';
|
||||
trim_whitespace(columns);
|
||||
|
||||
columns = trim_whitespace(columns);
|
||||
if (strlen(columns) == 0)
|
||||
{
|
||||
printf("Error: No columns defined for table '%s'.\n", table_name);
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
create_table(db, table_name, columns);
|
||||
}
|
||||
else if (strcmp(command, "INSERT") == 0)
|
||||
@ -327,53 +531,50 @@ void parse_query(Database *db, const char *query)
|
||||
if (next_token == NULL || strcmp(next_token, "INTO") != 0)
|
||||
{
|
||||
printf("Error: Invalid INSERT INTO syntax.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
table_name = strtok(NULL, " ");
|
||||
char *table_name = strtok(NULL, " ");
|
||||
if (table_name == NULL)
|
||||
{
|
||||
printf("Error: Table name is missing.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
columns = strchr(query, '(');
|
||||
if (columns == NULL)
|
||||
char *values = strchr(query, '(');
|
||||
if (values == NULL)
|
||||
{
|
||||
printf("Error: Missing values.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
columns++;
|
||||
char *closing_paren = strchr(columns, ')');
|
||||
values++;
|
||||
char *closing_paren = strchr(values, ')');
|
||||
if (closing_paren == NULL)
|
||||
{
|
||||
printf("Error: Missing closing parenthesis in values.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
*closing_paren = '\0';
|
||||
trim_whitespace(columns);
|
||||
|
||||
if (strlen(columns) == 0)
|
||||
values = trim_whitespace(values);
|
||||
if (strlen(values) == 0)
|
||||
{
|
||||
printf("Error: No values provided for table '%s'.\n", table_name);
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
insert_into_table(db, table_name, columns);
|
||||
insert_into_table(db, table_name, values);
|
||||
}
|
||||
else if (strcmp(command, "SELECT") == 0)
|
||||
{
|
||||
strtok(NULL, " ");
|
||||
strtok(NULL, " ");
|
||||
table_name = strtok(NULL, " ");
|
||||
/* Expected syntax: SELECT * FROM table_name */
|
||||
strtok(NULL, " "); // Skip '*'
|
||||
strtok(NULL, " "); // Skip 'FROM'
|
||||
char *table_name = strtok(NULL, " ");
|
||||
if (table_name == NULL)
|
||||
{
|
||||
printf("Error: Table name is missing in SELECT query.\n");
|
||||
return;
|
||||
return db;
|
||||
}
|
||||
|
||||
select_from_table(db, table_name);
|
||||
}
|
||||
else if (strcmp(command, "SAVE") == 0)
|
||||
@ -382,10 +583,12 @@ void parse_query(Database *db, const char *query)
|
||||
}
|
||||
else if (strcmp(command, "LOAD") == 0)
|
||||
{
|
||||
load_database_from_file(db, DB_FILE);
|
||||
db = load_database_from_file(db, DB_FILE);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error: Unsupported query.\n");
|
||||
}
|
||||
|
||||
return db;
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "linenoise.h"
|
||||
#include "db.h"
|
||||
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
char *query;
|
||||
Database *db;
|
||||
@ -34,12 +33,14 @@ int main()
|
||||
|
||||
if (strlen(query) > 0)
|
||||
{
|
||||
parse_query(db, query);
|
||||
db = parse_query(db, query);
|
||||
linenoiseHistoryAdd(query);
|
||||
}
|
||||
|
||||
free(query);
|
||||
}
|
||||
|
||||
free_database(db);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user