Add language editing and filtering.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
DROP VIEW manydecks.summaries;
|
||||
|
||||
CREATE VIEW manydecks.summaries AS
|
||||
SELECT
|
||||
decks.id,
|
||||
users.name as author,
|
||||
users.id as author_id,
|
||||
decks.version,
|
||||
decks.deck->>'name' as name,
|
||||
decks.deck->>'language' as language,
|
||||
jsonb_array_length(decks.deck->'calls') as calls,
|
||||
jsonb_array_length(decks.deck->'responses') as responses,
|
||||
((decks.deck ? 'public') and (decks.deck->'public')::bool) as public,
|
||||
(setweight(to_tsvector('english', coalesce(decks.deck->>'name', '')), 'A') ||
|
||||
setweight(to_tsvector('english', decks.deck->'calls'), 'D') ||
|
||||
setweight(to_tsvector('english', decks.deck->'responses'), 'D')
|
||||
) as deck_search
|
||||
FROM
|
||||
manydecks.decks INNER JOIN manydecks.users ON users.id = decks.author;
|
||||
|
||||
|
||||
CREATE OR REPLACE VIEW manydecks.languages AS
|
||||
SELECT decks.deck->>'language' AS code
|
||||
FROM manydecks.decks
|
||||
WHERE ((decks.deck ? 'public') AND (decks.deck->'public')::bool)
|
||||
GROUP BY code
|
||||
ORDER BY count(*) DESC
|
||||
@@ -98,6 +98,10 @@ const main = async (): Promise<void> => {
|
||||
});
|
||||
});
|
||||
|
||||
app.get("/api/languages", async (req, res) => {
|
||||
res.json(await store.languages());
|
||||
});
|
||||
|
||||
app.post("/api/users", async (req, res) => {
|
||||
if (req.body.token !== undefined) {
|
||||
const claims = auth.validate(req.body.token);
|
||||
@@ -153,9 +157,10 @@ const main = async (): Promise<void> => {
|
||||
|
||||
app.get("/api/decks/browse", async (req, res) => {
|
||||
const page = req.query.p as string;
|
||||
const language = req.query.l as string;
|
||||
const query = req.query.q as string;
|
||||
const decks = await store.browse(query, parseInt(page));
|
||||
res.json(Array.from(decks));
|
||||
const decks = await store.browse(query, language, parseInt(page));
|
||||
res.json([...decks]);
|
||||
});
|
||||
|
||||
app.get("/api/decks/:deckCode", async (req, res) => {
|
||||
@@ -193,7 +198,7 @@ const main = async (): Promise<void> => {
|
||||
}
|
||||
const userId = req.params.userId;
|
||||
const decks = await store.getSummariesForUser(userId, requester !== userId);
|
||||
res.json(Array.from(decks));
|
||||
res.json([...decks]);
|
||||
});
|
||||
|
||||
app.post("/api/backup", async (req, res) => {
|
||||
|
||||
+16
-6
@@ -58,6 +58,14 @@ export class Store {
|
||||
this.issuer = issuer;
|
||||
}
|
||||
|
||||
public languages: () => Promise<string[]> = async () =>
|
||||
await this.withClient(async (client) => {
|
||||
const result = await client.query(
|
||||
`SELECT code FROM manydecks.languages;`
|
||||
);
|
||||
return result.rows.map((row) => row.code);
|
||||
});
|
||||
|
||||
public findOrCreateUser: (
|
||||
googleId: string,
|
||||
googleName?: string
|
||||
@@ -282,34 +290,36 @@ export class Store {
|
||||
|
||||
public browse: (
|
||||
query?: string,
|
||||
language?: string,
|
||||
page?: number
|
||||
) => Promise<Iterable<Deck.CodeAndSummary>> = async (query, page) =>
|
||||
) => Promise<Iterable<Deck.CodeAndSummary>> = async (query, language, page) =>
|
||||
await this.withClient(async (client) => {
|
||||
const pageSize = 20;
|
||||
const p = page === undefined ? 0 : page;
|
||||
const l = language === undefined ? null : language;
|
||||
let result;
|
||||
if (query === undefined) {
|
||||
result = await client.query(
|
||||
`
|
||||
SELECT id, name, author_id, author, language, calls, responses, public, version
|
||||
FROM manydecks.summaries
|
||||
WHERE summaries.public
|
||||
WHERE summaries.public AND ($3::text IS NULL OR summaries.language = $3::text)
|
||||
ORDER BY id DESC
|
||||
OFFSET $1::int * $2::int LIMIT $2
|
||||
`,
|
||||
[p, pageSize]
|
||||
[p, pageSize, l]
|
||||
);
|
||||
} else {
|
||||
result = await client.query(
|
||||
`
|
||||
SELECT id, name, author_id, author, language, calls, responses, public, version, ts_rank_cd(deck_search , query) AS rank
|
||||
FROM manydecks.summaries, to_tsquery($3) query
|
||||
WHERE summaries.public
|
||||
FROM manydecks.summaries, to_tsquery($4) query
|
||||
WHERE summaries.public AND ($3::text IS NULL OR summaries.language = $3::text)
|
||||
AND query @@ summaries.deck_search
|
||||
ORDER BY rank DESC
|
||||
OFFSET $1::int * $2::int LIMIT $2
|
||||
`,
|
||||
[p, pageSize, query]
|
||||
[p, pageSize, l, query]
|
||||
);
|
||||
}
|
||||
return Store.summariesFromRows(result);
|
||||
|
||||
Reference in New Issue
Block a user