Finish step 5

This commit is contained in:
Timothy Warren 2017-09-11 11:49:58 -04:00
parent 103ab099c1
commit f85583c4cc
2 changed files with 77 additions and 4 deletions

75
db.c
View File

@ -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;

View File

@ -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