create table bolt_user (
    user_id         integer         not null,
    birth_year      integer         not null,
    sex             tinyint         not null,
    debug           tinyint         not null,
        -- if nonzero, print debug info everywhere
    attrs           text            not null,
    primary key (user_id)
);

create table bolt_course (
    id              integer         not null auto_increment,
    create_time     integer         not null,
    short_name      varchar(255)    not null,
    name            varchar(255)    not null,
    description     text            not null,
    doc_file        varchar(255)    not null,
    primary key (id)
);

create table bolt_enrollment (
    create_time     integer         not null,
    user_id         integer         not null,
    course_id       integer         not null,
    last_view_id    integer         not null,
    mastery         double          not null
);

-- Represents a view of an item;
-- created when we show the item,
-- and finalized when the user clicks on something to leave the page
-- A special view is used to represent the end of a course;
-- its mode is BOLT_MODE_FINISHED.
--
create table bolt_view (
    id              integer         not null auto_increment,
    user_id         integer         not null,
    course_id       integer         not null,
    item_name       varchar(255)    not null,
        -- name of the item
    state           text            not null,
        -- course state
    mode            integer         not null,
        -- distinguishes exercise show/answer
    action          integer         not null,
        -- what the user clicked
    start_time      integer         not null,
    end_time        integer         not null,
    prev_view_id    integer         not null,
        -- for exercise answer views,
        -- this always refers to the original exercise show
    fraction_done   double          not null,
    result_id       integer         not null,
        -- if this was an exercise show, link to result record
    refresh_id      integer         not null,
        -- if unit was flagged for review, link to review record
    primary key (id)
);

-- represents the result of a single exercise
--
create table bolt_result (
    id              integer         not null auto_increment,
    create_time     integer         not null,
    user_id         integer         not null,
    course_id       integer         not null,
    view_id         integer         not null,
        -- the original display of exercise
    score           double          not null,
    response        text            not null,
        -- the query string containing user's responses
    primary key(id)
);

-- represents the result of a completed exercise set,
-- where "completed" means the student clicked Next on the final answer page.
-- This is slightly redundant -
-- it could be reconstructed from the individual exercise results -
-- but this way makes it easier for analytics to treat exercise sets as units.
--
create table bolt_xset_result (
    id              integer         not null auto_increment,
    create_time     integer         not null,
    user_id         integer         not null,
    course_id       integer         not null,
    name            varchar(255)    not null,
        -- logical name of result set unit
    score           double          not null,
    view_id         integer         not null,
        -- the answer page of last exercise in set
    primary key(id)
);

-- represents a refresh/repeat of an exercise set,
-- either pending (not due yet),
-- due but not started, or in progress.
--
create table bolt_refresh (
    id              integer         not null auto_increment,
    create_time     integer         not null,
    user_id         integer         not null,
    course_id       integer         not null,
    name            varchar(255)    not null,
        -- logical name of result set unit
    last_view_id    integer         not null,
        -- if refresh is in progress, the last view
    set_result_id   integer         not null,
        -- most recent result for this set
    due_time        integer         not null,
        -- when refresh will be due
    primary key (id)
);
