Esempio n. 1
0
File: sync.c Progetto: atikinn/db165
static inline
void persist_meta(char *meta, size_t sz) {
    char buf[PATHLEN];
    char *path = vbsnprintf(buf, sizeof buf, "%s/%s.bin", DBPATH, METAFILE);
    persist_data(meta, sz, sizeof (char), path);
    if (path != buf) free(path);
    return;
}
Esempio n. 2
0
File: sync.c Progetto: atikinn/db165
static inline
void persist_col(struct column *col, const char *tname) {
    if (col->status == ONDISK || col->status == INMEMORY) return;

    char buf[PATHLEN];
    char *path = vbsnprintf(buf, sizeof buf, "%s/%s.%s.bin", DBPATH, tname, col->name);
    cs165_log(stderr, "%s: %s\n", tname, path);
    persist_data(col->data.vals, col->data.sz, sizeof (int), path);
    if (path != buf) free(path);
    if (col->index) persist_index(col, col->table->name);
}
Esempio n. 3
0
File: sync.c Progetto: atikinn/db165
static inline
void persist_index(struct column *col, const char *tname) {
    char buf[PATHLEN];
    char *path;
    switch(col->index->type) {
	case SORTED:
	    path = vbsnprintf(buf, sizeof buf, "%s/%s.%s.sorted.bin", DBPATH, tname, col->name);
	    cs165_log(stderr, "%s: %s\n", tname, path);
	    persist_data(col->index->index, col->data.sz, sizeof (struct sindex), path);
	    if (path != buf) free(path);
	case BTREE: break; // TODO: expensive, easier to fully reconstruct
	case IDX_INVALID: break;
    }
}
Esempio n. 4
0
/**
 * handle_client(client_socket)
 * This is the execution routine after a client has connected.
 * It will continually listen for messages from the client and execute queries.
 **/
void handle_client(int client_socket) {
    int done = 0;
    int length = 0;

    log_info("Connected to socket: %d.\n", client_socket);

    // Create two messages, one from which to read and one from which to receive
    message send_message;
    message recv_message;

    // Continually receive messages from client and execute queries.
    // 1. Parse the command
    // 2. Handle request if appropriate
    // 3. Send status of the received message (OK, UNKNOWN_QUERY, etc)
    // 4. Send response of request.
    do {
        length = recv(client_socket, &recv_message, sizeof(message), 0);
        if (length < 0) {
            log_err("Client connection closed!\n");
            exit(1);
        } else if (length == 0) {
            done = 1;
        }

        if (recv_message.status == LOAD_REQUEST) {
            char recv_buffer[recv_message.length];
            length = recv(client_socket, recv_buffer, recv_message.length,0);
            recv_message.payload = recv_buffer;
            recv_message.payload[recv_message.length] = '\0';

            char* col_name = strtok(recv_buffer, ",");
            int tbl_idx = find_table_from_col_name(col_name);
            if (tbl_idx == -1) {
                log_err("Cannot find table.\n");
                exit(1);
            }
            table* tbl = global_db->tables[tbl_idx];

            while((length = recv(client_socket, &recv_message, sizeof(message), 0)) > 0) {
                if (recv_message.status == OK_WAIT_FOR_RESPONSE &&
                        (int) recv_message.length > 0) {
                    // Calculate number of bytes in response package
                    size_t num_bytes = recv_message.length;
                    char payload[num_bytes + 1];

                    if ((length = recv(client_socket, payload, num_bytes, 0)) > 0) {
                        db_operator* dbo = init_dbo();
                        status s = relational_insert(tbl_idx, payload, dbo);
                        if (s.code != OK) {
                            log_err(s.error_message);
                            exit(1);
                        }
                        char* result = execute_db_operator(dbo);
                        log_info("%s\n", result);
                    }
                } else if (recv_message.status == LOAD_DONE) {
                    status s = process_indexes(tbl);
                    char* result = "Bulk load done";
                    if (s.code != OK) {
                        result = s.error_message;
                    }

                    send_message.status = OK_WAIT_FOR_RESPONSE;
                    send_message.type = CHAR;
                    send_message.length = strlen(result);

                    // 3. Send status of the received message (OK, UNKNOWN_QUERY, etc)
                    if (send(client_socket, &(send_message), sizeof(message), 0) == -1) {
                        log_err("Failed to send message.");
                        exit(1);
                    }

                    // 4. Send response of request
                    if (send(client_socket, result, send_message.length, 0) == -1) {
                        log_err("Failed to send message.");
                        exit(1);
                    }

                    break;
                }
            }
            continue;
        }

        if (!done) {
            char recv_buffer[recv_message.length];
            length = recv(client_socket, recv_buffer, recv_message.length,0);
            recv_message.payload = recv_buffer;
            recv_message.payload[recv_message.length] = '\0';

            // 1. Parse command
            status parse_status;
            db_operator* query = parse_command(&recv_message, &send_message, &parse_status);

            // 2. Handle request
            char* result = NULL;
            if (parse_status.code != OK) {
                // Something went wrong
                result = parse_status.error_message;
                send_message.type = CHAR;
                send_message.length = strlen(result);
                
            } else if (query->type == TUPLE) {
                send_message.type = query->tups->type;
                send_message.num_rows = query->tups->num_rows;
                send_message.num_cols = query->tups->num_cols;
                send_message.length = (int) (send_message.num_rows * send_message.num_cols);

                if (send_message.type == INT) {
                    send_message.length *= sizeof(int);
                } else if (send_message.type == LONG) {
                    send_message.length *= sizeof(long);
                } else if (send_message.type == LONG_DOUBLE) {
                    send_message.length *= sizeof(long double);
                } else {
                    send_message.length *= sizeof(char);
                }

                // 3. Send status of the received message (OK, UNKNOWN_QUERY, etc)
                if (send(client_socket, &(send_message), sizeof(message), 0) == -1) {
                    log_err("Failed to send message.");
                    exit(1);
                }

                // 4. Send response of request
                for(size_t i = 0; i < send_message.num_cols; i++) {
                    char* result = (char*)query->tups->payloads[i];
                    int length = send_message.length/(int)send_message.num_cols;
                    if (send(client_socket, result, length, 0) == -1) {
                        log_err("Failed to send message.");
                        exit(1);
                    }
                }

                continue;

            } else if (query->type == SHUTDOWN) {
                status s = persist_data();
                if (s.code != OK) {
                    log_err("Error persisting data\n");
                }

                // free what you can
                // s = free_catalogs();
                if (s.code != OK) {
                    log_err("Error shutting down\n");
                }

                send_message.status = SHUTDOWN_CLIENT;
                if (send(client_socket, &(send_message), sizeof(message), 0) == -1) {
                    log_err("Failed to send message.");
                    close(client_socket);
                }

                return;
            } else {
                result = execute_db_operator(query);
                send_message.type = CHAR;
                send_message.length = strlen(result);
            }

            // 3. Send status of the received message (OK, UNKNOWN_QUERY, etc)
            if (send(client_socket, &(send_message), sizeof(message), 0) == -1) {
                log_err("Failed to send message.");
                exit(1);
            }

            // 4. Send response of request
            if (send(client_socket, result, send_message.length, 0) == -1) {
                log_err("Failed to send message.");
                exit(1);
            }
        }
    } while (!done);

    log_info("Connection closed at socket %d!\n", client_socket);
    close(client_socket);
}