266 lines
7.4 KiB
TypeScript
266 lines
7.4 KiB
TypeScript
import { Database } from "bun:sqlite";
|
|
import { wordFactorial } from "./utils";
|
|
|
|
// read
|
|
|
|
export function fetchResource(db: Database, spelling: string) {
|
|
const query = db.query(`
|
|
SELECT
|
|
spelling,
|
|
ipa,
|
|
frequency,
|
|
type,
|
|
subtype,
|
|
GROUP_CONCAT(c.name, ',') AS category,
|
|
FROM expressions
|
|
JOIN word_categories wc ON wc.word_id = words.id
|
|
JOIN categories c ON c.id = wc.category_id
|
|
WHERE spelling = $spelling
|
|
GROUP BY words.id
|
|
`);
|
|
return query.get({ spelling });
|
|
}
|
|
export function fetchFrequent(db: Database, count: number, page: number) {
|
|
const offset = (page - 1) * count;
|
|
const query = db.query(`
|
|
SELECT
|
|
spelling,
|
|
ipa,
|
|
frequency,
|
|
GROUP_CONCAT(c.name, ',') AS category,
|
|
FROM expressions e
|
|
JOIN word_categories wc ON wc.word_id = e.id
|
|
JOIN categories c ON c.id = wc.category_id
|
|
ORDER BY e.frequency DESC
|
|
LIMIT $count
|
|
OFFSET $offset
|
|
`);
|
|
return query.get({ count, offset });
|
|
}
|
|
export function fetchLessons(db: Database, count: number, page: number) {
|
|
const p = page < 1 ? 1 : page;
|
|
const offset = (p - 1) * count;
|
|
const queryString = `
|
|
SELECT
|
|
l.id, l.text as ltext, cards.text as ctext, cards.note as cnote, cards.id as cid,
|
|
e.spelling, e.ipa, e.frequency, e.id as eid,
|
|
GROUP_CONCAT(cg.name, ',') AS category
|
|
FROM expressions e
|
|
JOIN cards_expressions ce ON e.id = ce.expression_id
|
|
JOIN cards ON cards.id = cl.card_id
|
|
JOIN cards_lessons cl ON cl.card_id = cards.id
|
|
JOIN lessons l ON l.id = cl.lesson_id
|
|
JOIN expressions e ON e.id = ce.expression_id
|
|
JOIN word_categories wc ON wc.word_id = e.id
|
|
JOIN categories cg ON cg.id = wc.category_id
|
|
LIMIT $count
|
|
OFFSET $offset
|
|
`;
|
|
// const queryString = `
|
|
// SELECT
|
|
// l.id, l.text as ltext, cards.text as ctext, cards.note as cnote, cards.id as cid
|
|
// FROM cards_lessons cl
|
|
// JOIN lessons l ON l.id = cl.lesson_id
|
|
// JOIN cards ON cards.id = cl.card_id
|
|
// LIMIT $count
|
|
// OFFSET $offset
|
|
// `;
|
|
const query = db.query(queryString);
|
|
const res = query.all({ count, offset });
|
|
return res;
|
|
}
|
|
|
|
// SELECT l.id, l.text, cards.text, cards.note FROM cards_lessons cl LEFT JOIN lessons l ON l.id = cl.lesson_id LEFT JOIN cards ON cards.id = cl.card_id ORDER BY l.id ASC LIMIT 20 OFFSET 0;
|
|
export function fetchLesson(db: Database, lesson: number) {
|
|
const queryString = `
|
|
SELECT
|
|
l.id, l.text, cards.text, cards.note, cards.id as cid,
|
|
spelling, ipa, frequency, e.id as eid,
|
|
GROUP_CONCAT(cg.name, ',') AS category
|
|
FROM cards_lessons cl
|
|
JOIN lessons l ON l.id = cl.lesson_id
|
|
JOIN cards ON cards.id = lc.card_id
|
|
JOIN cards_expressions ce ON cards.id = ce.card_id
|
|
JOIN expressions e ON e.id = ce.expression_id
|
|
JOIN word_categories wc ON wc.word_id = e.id
|
|
JOIN categories cg ON cg.id = wc.category_id
|
|
WHERE l.id = $lesson
|
|
`;
|
|
console.log(queryString);
|
|
const query = db.query(queryString);
|
|
return query.all({ lesson });
|
|
}
|
|
export function fetchCard(db: Database, cid: number, userid: number) {
|
|
const query = db.query(`
|
|
SELECT
|
|
l.id, l.text, cards.text, cards.note
|
|
FROM cards_lessons cl
|
|
JOIN lessons l ON l.id = cl.lesson_id
|
|
JOIN cards ON cards.id = lc.card_id
|
|
JOIN attempts a ON a.card_id = cards.id AND a.user_id = $userid
|
|
WHERE cards.id = $cid
|
|
`);
|
|
return query.all({ cid, userid });
|
|
}
|
|
|
|
// write
|
|
export function addLesson(db: Database, text: string) {
|
|
const query = db.query(`
|
|
INSERT
|
|
INTO lessons(text)
|
|
VALUES($text)
|
|
`);
|
|
const res = query.run({ text });
|
|
return res.lastInsertRowid;
|
|
}
|
|
export function addCard(
|
|
db: Database,
|
|
lesson_id: number | bigint | null,
|
|
text: string,
|
|
mnote?: string,
|
|
) {
|
|
const note = mnote ? mnote : null;
|
|
const query = db.query(`
|
|
INSERT
|
|
INTO cards(text, note)
|
|
VALUES($text, $note)
|
|
`);
|
|
const params = { text, note, spel: text };
|
|
const res = query.run(params);
|
|
const cid = res.lastInsertRowid;
|
|
const wquery = db.query(`
|
|
INSERT OR IGNORE
|
|
INTO cards_expressions(card_id, expression_id)
|
|
VALUES($cid, (
|
|
SELECT id FROM expressions e
|
|
WHERE e.spelling LIKE $spelling
|
|
))
|
|
`);
|
|
const wtr = db.transaction((pairs) => {
|
|
for (const pair of pairs) wquery.run(pair);
|
|
});
|
|
const words = text
|
|
.replace(/[^\w\s]/g, "")
|
|
.replace(/\s+/g, " ")
|
|
.trim()
|
|
.split(" ");
|
|
const combinations = wordFactorial(words);
|
|
const richWords = combinations.map((spelling) => {
|
|
return { spelling, cid };
|
|
});
|
|
wtr(richWords);
|
|
if (lesson_id) {
|
|
const query = db.query(`
|
|
INSERT INTO cards_lessons(card_id, lesson_id)
|
|
VALUES($cid, $lesson_id)
|
|
`);
|
|
query.run({ lesson_id, cid });
|
|
}
|
|
}
|
|
|
|
export function addUser(db: Database, name: string, creds: string) {
|
|
const query = db.query(`
|
|
INSERT
|
|
INTO users(name, creds)
|
|
VALUES($name, $creds)
|
|
`);
|
|
query.run({ $name: name, $creds: creds });
|
|
}
|
|
|
|
export function addWord(
|
|
db: Database,
|
|
spelling: string,
|
|
ipa: string,
|
|
language: string,
|
|
type: string,
|
|
subtype: string | null,
|
|
) {
|
|
const queryString = `
|
|
INSERT
|
|
INTO expressions(spelling, ipa, type, subtype, frequency, language_id)
|
|
VALUES($spelling, $ipa, $type, $subtype, 0, (
|
|
SELECT id FROM languages
|
|
WHERE name = $language
|
|
))
|
|
`;
|
|
const query = db.prepare(queryString);
|
|
const res = query.run({ spelling, ipa, language, type, subtype });
|
|
return res.lastInsertRowid;
|
|
}
|
|
export function addCat(db: Database, wordId: number | bigint, domain: string) {
|
|
const queryString = `
|
|
INSERT
|
|
INTO word_categories(word_id, category_id)
|
|
VALUES($wordId, (
|
|
SELECT id FROM categories
|
|
WHERE name = $category
|
|
))
|
|
`;
|
|
const category = domains[domain] || "unknown";
|
|
const query = db.query(queryString);
|
|
const res = query.run({ wordId, category });
|
|
return res.lastInsertRowid;
|
|
}
|
|
|
|
const domains: Record<string, string> = {
|
|
"adj.all": "adjective",
|
|
"adj.pert": "adjective",
|
|
"adj.ppl": "adjective",
|
|
"adv.all": "adverb",
|
|
"noun.Tops": "",
|
|
"noun.act": "abstract",
|
|
"noun.animal": "animate",
|
|
"noun.artifact": "inanimate",
|
|
"noun.attribute": "abstract",
|
|
"noun.body": "inanimate",
|
|
"noun.cognition": "abstract",
|
|
"noun.communication": "abstract",
|
|
"noun.event": "abstract",
|
|
"noun.feeling": "abstract",
|
|
"noun.food": "inanimate",
|
|
"noun.group": "noun",
|
|
"noun.location": "spatial",
|
|
"noun.motive": "abstract",
|
|
"noun.object": "inanimate",
|
|
"noun.person": "animate",
|
|
"noun.phenomenon": "abstract",
|
|
"noun.plant": "noun",
|
|
"noun.possession": "noun",
|
|
"noun.process": "noun",
|
|
"noun.quantity": "uncountable",
|
|
"noun.relation": "noun",
|
|
"noun.shape": "noun",
|
|
"noun.state": "noun",
|
|
"noun.substance": "uncountable",
|
|
"noun.time": "temporal",
|
|
"verb.body": "verb",
|
|
"verb.change": "verb",
|
|
"verb.cognition": "verb",
|
|
"verb.communication": "verb",
|
|
"verb.competition": "verb",
|
|
"verb.consumption": "verb",
|
|
"verb.contact": "verb",
|
|
"verb.creation": "verb",
|
|
"verb.emotion": "mental",
|
|
"verb.motion": "verb",
|
|
"verb.perception": "mental",
|
|
"verb.possession": "verb",
|
|
"verb.social": "verb",
|
|
"verb.stative": "verb",
|
|
"verb.weather": "verb",
|
|
};
|
|
export function addFrequency(
|
|
db: Database,
|
|
spelling: string,
|
|
frequency: number,
|
|
) {
|
|
const queryString = `
|
|
UPDATE expressions
|
|
SET frequency = $frequency
|
|
WHERE expressions.spelling = $spelling
|
|
`;
|
|
const query = db.query(queryString);
|
|
const res = query.run({ spelling, frequency });
|
|
console.log(res, "added frequency");
|
|
}
|