Finish step 5
This commit is contained in:
parent
103ab099c1
commit
f85583c4cc
75
db.c
75
db.c
@ -114,8 +114,70 @@ void read_input(InputBuffer* input_buffer) {
|
||||
input_buffer->buffer[bytes_read - 1] = 0;
|
||||
}
|
||||
|
||||
MetaCommandResult do_meta_command(InputBuffer* input_buffer) {
|
||||
void pager_flush(Pager* pager, uint32_t page_num, uint32_t size) {
|
||||
if (pager->pages[page_num] == NULL) {
|
||||
printf("Tried to flush null page\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
off_t offset = lseek(pager->file_descriptor, page_num * PAGE_SIZE, SEEK_SET);
|
||||
|
||||
if (offset == -1) {
|
||||
printf("Error seeking: %d\n", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ssize_t bytes_written = write(pager->file_descriptor, pager->pages[page_num], size);
|
||||
|
||||
if (bytes_written == -1) {
|
||||
printf("Error writing: %d\n", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void db_close(Table* table) {
|
||||
Pager* pager = table->pager;
|
||||
uint32_t num_full_pages = table->num_rows / ROWS_PER_PAGE;
|
||||
|
||||
for (uint32_t i = 0; i < num_full_pages; i++) {
|
||||
if (pager->pages[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
pager_flush(pager, i, PAGE_SIZE);
|
||||
free(pager->pages[i]);
|
||||
pager->pages[i] = NULL;
|
||||
}
|
||||
|
||||
// There may be a partial page to write to the end of the file
|
||||
// This should not be needed after we switch to a B-tree
|
||||
uint32_t num_additional_rows = table->num_rows % ROWS_PER_PAGE;
|
||||
if (num_additional_rows > 0) {
|
||||
uint32_t page_num = num_full_pages;
|
||||
if (pager->pages[page_num] != NULL) {
|
||||
pager_flush(pager, page_num, num_additional_rows * ROW_SIZE);
|
||||
free(pager->pages[page_num]);
|
||||
pager->pages[page_num] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int result = close(pager->file_descriptor);
|
||||
if (result == -1) {
|
||||
printf("Error closing db file.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for(uint32_t i = 0; i < TABLE_MAX_PAGES; i++) {
|
||||
void* page = pager->pages[i];
|
||||
if (page) {
|
||||
free(page);
|
||||
pager->pages[i] = NULL;
|
||||
}
|
||||
}
|
||||
free(pager);
|
||||
}
|
||||
|
||||
MetaCommandResult do_meta_command(InputBuffer* input_buffer, Table* table) {
|
||||
if (strcmp(input_buffer->buffer, ".exit") == 0) {
|
||||
db_close(table);
|
||||
exit(EXIT_SUCCESS);
|
||||
} else {
|
||||
return META_COMMAND_UNRECOGNIZED_COMMAND;
|
||||
@ -285,14 +347,21 @@ Table* db_open(const char* filename) {
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
Table* table = new_table();
|
||||
if (argc < 2) {
|
||||
printf("Must supply a database filename\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char* filename = argv[1];
|
||||
Table* table = db_open(filename);
|
||||
|
||||
InputBuffer* input_buffer = new_input_buffer();
|
||||
while (true) {
|
||||
print_prompt();
|
||||
read_input(input_buffer);
|
||||
|
||||
if (input_buffer->buffer[0] == '.') {
|
||||
switch (do_meta_command(input_buffer)) {
|
||||
switch (do_meta_command(input_buffer, table)) {
|
||||
case (META_COMMAND_SUCCESS):
|
||||
continue;
|
||||
|
||||
|
@ -1,7 +1,11 @@
|
||||
describe 'database' do
|
||||
before do
|
||||
`rm -rf test.db`
|
||||
end
|
||||
|
||||
def run_script(commands)
|
||||
raw_output = nil
|
||||
IO.popen("./db", "r+") do |pipe|
|
||||
IO.popen("./db test.db", "r+") do |pipe|
|
||||
commands.each do |command|
|
||||
pipe.puts command
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user