-
Notifications
You must be signed in to change notification settings - Fork 0
/
db.h
234 lines (215 loc) · 6.86 KB
/
db.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/********************************************************************
db.h - This file contains all the structures, defines, and function
prototype for the db.exe program.
*********************************************************************/
#define MAX_IDENT_LEN 16
#define MAX_NUM_COL 16
#define MAX_TOK_LEN 32
#define KEYWORD_OFFSET 10
#define STRING_BREAK " (),<>="
#define NUMBER_BREAK " ),"
#define TIMESTAMP_LEN 14
#define LOG_F "db.log"
#define DB_F "dbfile.bin"
/* Column descriptor sturcture = 20+4+4+4+4 = 36 bytes */
typedef struct cd_entry_def
{
char col_name[MAX_IDENT_LEN+4];
int col_id; /* Start from 0 */
int col_type;
int col_len;
int not_null;
} cd_entry;
/* Table packed descriptor sturcture = 4+20+4+4+4 = 36 bytes
Minimum of 1 column in a table - therefore minimum size of
1 valid tpd_entry is 36+36 = 72 bytes. */
typedef struct tpd_entry_def
{
int tpd_size;
char table_name[MAX_IDENT_LEN+4];
int num_columns;
int cd_offset;
int tpd_flags;
} tpd_entry;
/* Table packed descriptor list = 4+4+4+36 = 48 bytes. When no
table is defined the tpd_list is 48 bytes. When there is
at least 1 table, then the tpd_entry (36 bytes) will be
overlapped by the first valid tpd_entry. */
typedef struct tpd_list_def
{
int list_size;
int num_tables;
int db_flags;
tpd_entry tpd_start;
}tpd_list;
typedef struct table_file_header_def
{
int file_size; // 4 bytes
int record_size; // 4 bytes
int num_records; // 4 bytes
int record_offset; // 4 bytes
int file_header_flag; // 4 bytes
tpd_entry *tpd_ptr; // 4 bytes
} table_file_header; // minimum size = 24
/* This token_list definition is used for breaking the command
string into separate tokens in function get_tokens(). For
each token, a new token_list will be allocated and linked
together. */
typedef struct t_list
{
char tok_string[MAX_TOK_LEN];
int tok_class;
int tok_value;
struct t_list *next;
} token_list;
/* This enum defines the different classes of tokens for
semantic processing. */
typedef enum t_class
{
keyword = 1, // 1
identifier, // 2
symbol, // 3
type_name, // 4
constant, // 5
function_name,// 6
terminator, // 7
error // 8
} token_class;
/* This enum defines the different values associated with
a single valid token. Use for semantic processing. */
typedef enum t_value
{
T_INT = 10, // 10 - new type should be added above this line
T_CHAR, // 11
K_CREATE, // 12
K_TABLE, // 13
K_NOT, // 14
K_NULL, // 15
K_DROP, // 16
K_LIST, // 17
K_SCHEMA, // 18
K_FOR, // 19
K_TO, // 20
K_INSERT, // 21
K_INTO, // 22
K_VALUES, // 23
K_DELETE, // 24
K_FROM, // 25
K_WHERE, // 26
K_UPDATE, // 27
K_SET, // 28
K_SELECT, // 29
K_ORDER, // 30
K_BY, // 31
K_DESC, // 32
K_IS, // 33
K_AND, // 34
K_OR, // 35 - new keyword should be added below this line
K_BACKUP,
K_RESTORE,
K_WITHOUT,
K_RF,
K_ROLLFORWARD,
F_SUM, // 36
F_AVG, // 37
F_COUNT, // 38 - new function name should be added below this line
S_LEFT_PAREN = 70, // 70
S_RIGHT_PAREN, // 71
S_COMMA, // 72
S_STAR, // 73
S_EQUAL, // 74
S_LESS, // 75
S_GREATER, // 76
IDENT = 85, // 85
INT_LITERAL = 90, // 90
STRING_LITERAL, // 91
EOC = 95, // 95
INVALID = 99 // 99
} token_value;
/* This constants must be updated when add new keywords */
#define TOTAL_KEYWORDS_PLUS_TYPE_NAMES 34
/* New keyword must be added in the same position/order as the enum
definition above, otherwise the lookup will be wrong */
char *keyword_table[] =
{
"int", "char", "create", "table", "not", "null", "drop", "list", "schema",
"for", "to", "insert", "into", "values", "delete", "from", "where",
"update", "set", "select", "order", "by", "desc", "is", "and", "or",
"backup", "restore", "without", "rf", "rollforward",
"sum", "avg", "count"
};
/* This enum defines a set of possible statements */
typedef enum s_statement
{
INVALID_STATEMENT = -199, // -199
CREATE_TABLE = 100, // 100
DROP_TABLE, // 101
LIST_TABLE, // 102
LIST_SCHEMA, // 103
INSERT, // 104
DELETE, // 105
UPDATE, // 106
SELECT, // 107
BACKUP,
RESTORE,
ROLLFORWARD
} semantic_statement;
/* This enum has a list of all the errors that should be detected
by the program. Can append to this if necessary. */
typedef enum error_return_codes
{
INVALID_TABLE_NAME = -399, // -399
DUPLICATE_TABLE_NAME, // -398
TABLE_NOT_EXIST, // -397
INVALID_TABLE_DEFINITION, // -396
INVALID_COLUMN_NAME, // -395
DUPLICATE_COLUMN_NAME, // -394
COLUMN_NOT_EXIST, // -393
MAX_COLUMN_EXCEEDED, // -392
INVALID_TYPE_NAME, // -391
INVALID_COLUMN_DEFINITION, // -390
INVALID_COLUMN_LENGTH, // -389
INVALID_REPORT_FILE_NAME, // -388
INVALID_NO_TABLE_CONTENT, // -387
/* Must add all the possible errors from I/U/D + SELECT here */
FILE_OPEN_ERROR = -299, // -299
DBFILE_CORRUPTION, // -298
MEMORY_ERROR , // -297
FILE_DELETE_ERROR, // -296
FILE_EXISTS_ERROR,
ROLLFORWARD_PENDING
} return_codes;
/* Set of function prototypes */
int process(char *stmt, char r);
int get_token(char *command, token_list **tok_list);
void add_to_list(token_list **tok_list, char *tmp, int t_class, int t_value);
int do_semantic(token_list *tok_list, char *stmt);
int sem_create_table(token_list *t_list);
int sem_drop_table(token_list *t_list);
int sem_list_tables();
int sem_list_schema(token_list *t_list);
int sem_insert_stmt(token_list *t_list);
int sem_select_stmt(token_list *t_list);
int sem_custom_stmt(token_list *t_list);
int sem_delete_stmt(token_list *t_list);
int sem_update_stmt(token_list *t_list);
int create_log_file();
int write_to_log_file(char* stmt, int cmd);
char *save_log_file();
int sem_backup_db(token_list *t_list);
int sem_restore_db(token_list *t_list);
int sem_rollforward_db(token_list *t_list);
int toggle_rollforward_flag();
int write_to_table_file(table_file_header *ntable, char *tablename);
table_file_header *read_from_table_file(char *table);
int initialize_table_list(char *tablename, int rec_size);
int delete_table_file(char * tablename);
/*
Keep a global list of tpd - in real life, this will be stored
in shared memory. Build a set of functions/methods around this.
*/
tpd_list *g_tpd_list;
int initialize_tpd_list();
int add_tpd_to_list(tpd_entry *tpd);
int drop_tpd_from_list(char *tabname);
tpd_entry* get_tpd_from_list(char *tabname);