db.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "db.h"
static char* get_field_name(int type) {
return field_type[type];
}
static int get_field_type(char* type) {
if(strcmp(type, "CHAR") == 0) {
return CHAR;
} else if(strcmp(type, "INT") == 0) {
return INT;
}
return UNKNOWN;
}
static int print_field(table_t* t) {
int i = 0;
printf("%-10s %-10s %5s %5s \n", "NAME", "TYPE", "LEN", "OFFSET");
for(i = 0; i < t->schema.field_cnt; i++) {
printf("%-10s %-10s %5d %5d \n", t->schema.field[i].name, get_field_name(t->schema.field[i].type),
t->schema.field[i].len, t->schema.field[i].offset);
}
printf("field_count[%d]\n", t->schema.field_cnt);
printf("fields_total_len[%d]\n", t->schema.fields_total_len);
return 0;
}
static int load_schema(table_t* t) {
char path[1024];
char type[128];
FILE* fp = NULL;
int i = 0;
int offset = 0;
int len = 0;
int padding = 0;
int ret = 0;
memset(t, 0x00, sizeof(table_t));
printf("input schema file \n");
fscanf(stdin, "%s", path);
fp = fopen(path, "r");
for(i = 0; 1; i++) {
ret = fscanf(fp, "%s %s %d", t->schema.field[t->schema.field_cnt].name, type, &t->schema.field[t->schema.field_cnt].len);
if(ret == EOF) break;
t->schema.field[t->schema.field_cnt].type = get_field_type(type);
t->schema.fields_total_len += t->schema.field[t->schema.field_cnt].len;
padding = (len % PADDING_SIZE) == 0 ? 0 : PADDING_SIZE - (len % PADDING_SIZE);
t->schema.field[t->schema.field_cnt].offset = offset;
offset += t->schema.field[t->schema.field_cnt].len;
t->schema.field_cnt++;
}
fclose(fp);
return 0;
}
static int showmenu() {
char line[128];
#ifdef WIN32
system("cls");
#else
system("clear");
#endif
printf("======================================================\n");
printf("================== DB TESTER =========================\n");
printf("======================================================\n");
printf("1. init table\n");
printf("2. show schema\n");
printf("3. insert data\n");
printf("4. show data\n");
printf("5. exit\n");
fgets(line, 127, stdin);
return atoi(line);
}
static int insert_data(FILE* fp, table_t* t) {
char value[128];
char record[128];
int i = 0;
void* savepos;
int int_val = 0;
for(i = 0; i < t->schema.field_cnt; i++) {
printf("%s] input : \n", t->schema.field[i].name);
fscanf(stdin, "%s", value);
savepos = record + t->schema.field[i].offset;
switch(t->schema.field[i].type) {
case CHAR:
memcpy(savepos, value, t->schema.field[i].len);
break;
case INT:
int_val = atoi(value);
memcpy(savepos, &int_val, t->schema.field[i].len);
default:
break;
}
}
fseek(fp, 0, SEEK_SET);
fwrite(record, t->schema.fields_total_len, 1, fp);
return 0;
}
static int show_data(FILE* fp, table_t* t) {
char value[128];
char record[128];
int i = 0;
int int_val = 0;
fseek(fp, 0, SEEK_SET);
fread(record, t->schema.fields_total_len, 1, fp);
for(i = 0; i < t->schema.field_cnt; i++) {
switch(t->schema.field[i].type) {
case CHAR:
memcpy(value, record + t->schema.field[i].offset, t->schema.field[i].len);
value[t->schema.field[i].len] = '\0';
printf("%s] : %s\n", t->schema.field[i].name, value);
break;
case INT:
memcpy(&int_val, record + t->schema.field[i].offset, t->schema.field[i].len);
printf("%s] : %d\n", t->schema.field[i].name, int_val);
default:
break;
}
}
return 0;
}
int main(int argc, char* argv[])
{
int menu = 0;
FILE* fp = NULL;
table_t table;
fp = fopen("access.db", "w+b");
while(1) {
menu = showmenu();
switch(menu) {
case 1:
load_schema(&table);
case 2:
print_field(&table);
break;
case 3:
insert_data(fp, &table);
break;
case 4:
show_data(fp, &table);
break;
default:
exit(0);
}
fgetc(stdin);
}
fclose(fp);
return 0;
}
첫댓글 와.. 형님 멋지십니다.ㅡ.ㅡ;;
barkley db를 이용하면 작은 DBMS를 쉽게 만들수 있지 않을까. 서울대에서는 이런거 학부때 프로젝트 한다던데..-_-
리눅스 C 인가요??? 대단합니다. JAVA만해서 리눅스 다 잊어버렸다ㅠ.ㅠ 쩝 하루하루 저급인력이 되는것 같아서 걱정 ^^:
별다른 system call이 없는 관계로..-_-;; 그리고 리눅스 C라는 말보다는 ANSI C라는 말이.. 일반적이죠. 대부분 서버OS들도 몇몇 ipc를 제외하고 POSIX 규칙을 따르면 포팅엔 문제가 없습니다. fork, CreateProcess 와의 차이가 가장 거시기 하죠.