Loading db schema
This commit is contained in:
1 parent
4646dad2b8
commit
68c24dcec5
3 files changed
+231
No files matched your search
@@ -0,0 +1,80 @@
|
|||||||
|
create table custom_fields
|
||||||
|
(
|
||||||
|
id integer
|
||||||
|
primary key,
|
||||||
|
name text not null,
|
||||||
|
identifier text not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table decks
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
name TEXT not null,
|
||||||
|
forward TEXT not null,
|
||||||
|
backward TEXT not null,
|
||||||
|
filter TEXT not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table settings
|
||||||
|
(
|
||||||
|
id text
|
||||||
|
primary key,
|
||||||
|
value text
|
||||||
|
);
|
||||||
|
|
||||||
|
create table word_groups
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
name TEXT not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table words
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
key TEXT not null,
|
||||||
|
value TEXT not null,
|
||||||
|
tags TEXT not null,
|
||||||
|
more TEXT,
|
||||||
|
group_id integer default 1 not null
|
||||||
|
constraint words_word_group_id_fk
|
||||||
|
references word_groups
|
||||||
|
on update cascade on delete cascade
|
||||||
|
);
|
||||||
|
|
||||||
|
create table history
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
deck_id INTEGER not null
|
||||||
|
references decks
|
||||||
|
on delete cascade,
|
||||||
|
word_id INTEGER not null
|
||||||
|
references words
|
||||||
|
on delete cascade,
|
||||||
|
timestamp INTEGER not null,
|
||||||
|
answer INTEGER not null,
|
||||||
|
before INTEGER not null,
|
||||||
|
after INTEGER not null,
|
||||||
|
fsrs INTEGER not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table states
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
word_id INTEGER not null
|
||||||
|
references words
|
||||||
|
on delete cascade,
|
||||||
|
deck_id INTEGER
|
||||||
|
references decks
|
||||||
|
on delete cascade,
|
||||||
|
score INTEGER default 1 not null,
|
||||||
|
last_opened integer not null,
|
||||||
|
fsrs_opened integer not null,
|
||||||
|
fsrs_memory integer not null,
|
||||||
|
fsrs_open_day integer not null
|
||||||
|
);
|
||||||
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// Числовые даты в БД JapLearn. Никаких TEXT/DATE-типов: всё — числа.
|
||||||
|
//
|
||||||
|
// Два формата:
|
||||||
|
// 1. «Дата-только» — число дней от 1970-01-01 (UTC).
|
||||||
|
// Поля: states.fsrs_opened, states.fsrs_open_day.
|
||||||
|
// Помощники: dateToEpochDay / epochDayToIso / isoToEpochDay.
|
||||||
|
// 2. Полный таймстамп — миллисекунды от 1970-01-01 (эпоха Unix, UTC).
|
||||||
|
// Поля: history.timestamp, states.last_opened.
|
||||||
|
// Помощники: dateToEpochMs / epochMsToIso / isoToEpochMs.
|
||||||
|
// (Предположение о единице измерения — см. ниже.)
|
||||||
|
|
||||||
|
/** Миллисекунд в одних сутках (UTC). */
|
||||||
|
export const DAY_MS = 86_400_000;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Формат «дата-только»: число дней от 1970-01-01.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Количество дней от 1970-01-01 (UTC) до указанной даты. */
|
||||||
|
export function dateToEpochDay(date: Date): number {
|
||||||
|
return Math.floor(date.getTime() / DAY_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Дата (полночь UTC) по номеру дня от 1970-01-01. */
|
||||||
|
export function epochDayToDate(day: number): Date {
|
||||||
|
return new Date(day * DAY_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ISO-формат 'YYYY-MM-DD' по номеру дня от 1970-01-01. */
|
||||||
|
export function epochDayToIso(day: number): string {
|
||||||
|
return epochDayToDate(day).toISOString().slice(0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Номер дня от 1970-01-01 по ISO-дате 'YYYY-MM-DD'. */
|
||||||
|
export function isoToEpochDay(iso: string): number {
|
||||||
|
return Math.floor(Date.parse(`${iso}T00:00:00Z`) / DAY_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Полный таймстамп: миллисекунды от 1970-01-01.
|
||||||
|
//
|
||||||
|
// ВАЖНО: единица измерения не зафиксирована в схеме. Здесь приняты
|
||||||
|
// миллисекунды (нативный формат JS Date). Если десктопная версия хранит
|
||||||
|
// секунды — поправить достаточно в одном месте (умножение на 1000).
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Таймстамп (мс) для даты. */
|
||||||
|
export function dateToEpochMs(date: Date): number {
|
||||||
|
return date.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Дата по таймстампу (мс). */
|
||||||
|
export function epochMsToDate(ms: number): Date {
|
||||||
|
return new Date(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ISO-строка (UTC) по таймстампу (мс). */
|
||||||
|
export function epochMsToIso(ms: number): string {
|
||||||
|
return epochMsToDate(ms).toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Таймстамп (мс) по ISO-строке. */
|
||||||
|
export function isoToEpochMs(iso: string): number {
|
||||||
|
return Date.parse(iso);
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
-- Схема базы данных JapLearn.
|
||||||
|
-- Источник истины: /dbschema.sql (корень проекта).
|
||||||
|
-- Здесь та же схема, но идемпотентная (CREATE TABLE IF NOT EXISTS),
|
||||||
|
-- чтобы выполнять её при инициализации БД без ошибок на уже готовой базе.
|
||||||
|
-- Все даты и таймстампы — числа. Поля-«даты» (fsrs_opened, fsrs_open_day)
|
||||||
|
-- хранят число дней от 1970-01-01 (UTC), остальные — таймстампы.
|
||||||
|
|
||||||
|
create table if not exists custom_fields
|
||||||
|
(
|
||||||
|
id integer
|
||||||
|
primary key,
|
||||||
|
name text not null,
|
||||||
|
identifier text not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists decks
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
name TEXT not null,
|
||||||
|
forward TEXT not null,
|
||||||
|
backward TEXT not null,
|
||||||
|
filter TEXT not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists settings
|
||||||
|
(
|
||||||
|
id text
|
||||||
|
primary key,
|
||||||
|
value text
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists word_groups
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
name TEXT not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists words
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
key TEXT not null,
|
||||||
|
value TEXT not null,
|
||||||
|
tags TEXT not null,
|
||||||
|
more TEXT,
|
||||||
|
group_id integer default 1 not null
|
||||||
|
constraint words_word_group_id_fk
|
||||||
|
references word_groups
|
||||||
|
on update cascade on delete cascade
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists history
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
deck_id INTEGER not null
|
||||||
|
references decks
|
||||||
|
on delete cascade,
|
||||||
|
word_id INTEGER not null
|
||||||
|
references words
|
||||||
|
on delete cascade,
|
||||||
|
timestamp INTEGER not null,
|
||||||
|
answer INTEGER not null,
|
||||||
|
before INTEGER not null,
|
||||||
|
after INTEGER not null,
|
||||||
|
fsrs INTEGER not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists states
|
||||||
|
(
|
||||||
|
id INTEGER
|
||||||
|
primary key autoincrement,
|
||||||
|
word_id INTEGER not null
|
||||||
|
references words
|
||||||
|
on delete cascade,
|
||||||
|
deck_id INTEGER
|
||||||
|
references decks
|
||||||
|
on delete cascade,
|
||||||
|
score INTEGER default 1 not null,
|
||||||
|
last_opened integer not null,
|
||||||
|
fsrs_opened integer not null,
|
||||||
|
fsrs_memory integer not null,
|
||||||
|
fsrs_open_day integer not null
|
||||||
|
);
|
||||||
Reference in new issue
Block a user