hanchu/server/db.ts

266 lines
7.4 KiB
TypeScript
Raw Normal View History

2024-10-22 08:45:52 +00:00
import { Database } from "bun:sqlite";
import { wordFactorial } from "./utils";
2024-10-22 04:35:21 +00:00
// 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
2024-10-22 08:45:52 +00:00
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
2024-10-22 04:35:21 +00:00
JOIN cards ON cards.id = cl.card_id
2024-10-22 08:45:52 +00:00
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
2024-10-22 04:35:21 +00:00
LIMIT $count
OFFSET $offset
`;
2024-10-22 08:45:52 +00:00
// 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
// `;
2024-10-22 04:35:21 +00:00
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
2024-10-22 08:45:52 +00:00
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
2024-10-22 04:35:21 +00:00
FROM cards_lessons cl
JOIN lessons l ON l.id = cl.lesson_id
JOIN cards ON cards.id = lc.card_id
2024-10-22 08:45:52 +00:00
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
2024-10-22 04:35:21 +00:00
WHERE l.id = $lesson
`;
2024-10-22 08:45:52 +00:00
console.log(queryString);
2024-10-22 04:35:21 +00:00
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)
`);
2024-10-22 08:45:52 +00:00
const params = { text, note, spel: text };
2024-10-22 04:35:21 +00:00
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
2024-10-22 08:45:52 +00:00
.replace(/[^\w\s]/g, "")
.replace(/\s+/g, " ")
2024-10-22 04:35:21 +00:00
.trim()
2024-10-22 08:45:52 +00:00
.split(" ");
2024-10-22 04:35:21 +00:00
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
))
`;
2024-10-22 08:45:52 +00:00
const category = domains[domain] || "unknown";
2024-10-22 04:35:21 +00:00
const query = db.query(queryString);
const res = query.run({ wordId, category });
return res.lastInsertRowid;
}
const domains: Record<string, string> = {
2024-10-22 08:45:52 +00:00
"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",
2024-10-22 04:35:21 +00:00
};
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 });
2024-10-22 08:45:52 +00:00
console.log(res, "added frequency");
2024-10-22 04:35:21 +00:00
}