112 lines
2.9 KiB
TypeScript
112 lines
2.9 KiB
TypeScript
/* global defineEventHandler getQuery, createError */
|
|
import { QueryObject } from "ufo";
|
|
|
|
import { data, database } from "../utils/database";
|
|
import { isString } from "../utils/isString";
|
|
import { client } from "~/utils/types/database";
|
|
|
|
type queryType = {
|
|
type: "before" | "after" | "around",
|
|
id: string
|
|
} | {
|
|
type: null
|
|
};
|
|
|
|
function getLocationParameterType(query: QueryObject): queryType {
|
|
const before = query.before;
|
|
const after = query.after;
|
|
const around = query.around;
|
|
|
|
let setLocationParametersCount = 0;
|
|
let rvalue: queryType = { type: null };
|
|
|
|
if (isString(before)) {
|
|
setLocationParametersCount++;
|
|
rvalue = { type: "before", id: before };
|
|
}
|
|
|
|
if (isString(after)) {
|
|
setLocationParametersCount++;
|
|
rvalue = { type: "after", id: after };
|
|
}
|
|
|
|
if (isString(around)) {
|
|
setLocationParametersCount++;
|
|
rvalue = { type: "around", id: around };
|
|
}
|
|
|
|
if (setLocationParametersCount > 1) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
message: "multiple location parameters not allowed",
|
|
});
|
|
}
|
|
|
|
return rvalue;
|
|
}
|
|
|
|
async function getResults(
|
|
queryType: queryType,
|
|
limit = 50,
|
|
) {
|
|
switch (queryType.type) {
|
|
case "before": {
|
|
const [data] = await database.query(
|
|
"SELECT *, CONVERT(`id`, CHAR) AS `id` FROM `clients` WHERE `id` < ? ORDER BY `id` DESC LIMIT ?",
|
|
[queryType.id, limit],
|
|
) as unknown as data<client>;
|
|
return data;
|
|
}
|
|
case "after": {
|
|
const [data] = await database.query(
|
|
"SELECT *, CONVERT(`id`, CHAR) AS `id` FROM `clients` WHERE `id` > ? ORDER BY `id` DESC LIMIT ?",
|
|
[queryType.id, limit],
|
|
) as unknown as data<client>;
|
|
return data;
|
|
}
|
|
case "around": {
|
|
const [data] = await database.query(
|
|
"(SELECT *, CONVERT(`id`, CHAR) AS `id` FROM `clients` WHERE `id` >= ? ORDER BY `id` ASC LIMIT ?)\n" +
|
|
"UNION ALL\n" +
|
|
"(SELECT *, CONVERT(`id`, CHAR) AS `id` FROM `clients` WHERE `id` < ? ORDER BY `id` DESC LIMIT ?)\n" +
|
|
"ORDER BY `id` DESC",
|
|
[queryType.id, Math.ceil(limit / 2), queryType.id, Math.floor(limit / 2)],
|
|
) as unknown as data<client>;
|
|
return data;
|
|
}
|
|
case null: {
|
|
const [data] = await database.query(
|
|
"SELECT *, CONVERT(`id`, CHAR) AS `id` FROM `clients` ORDER BY `id` DESC LIMIT ?",
|
|
[limit],
|
|
) as unknown as data<client>;
|
|
return data;
|
|
}
|
|
default:
|
|
throw createError("Not implemented");
|
|
}
|
|
}
|
|
|
|
export default defineEventHandler(async (e) => {
|
|
const query = getQuery(e);
|
|
|
|
let limit = 50;
|
|
if (query.limit) limit = Number(query.limit);
|
|
if (limit > 200) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
message: "Cannot retrieve more than 200 records",
|
|
});
|
|
}
|
|
if (limit <= 0) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
message: "Tried to retireve 0 or less records",
|
|
});
|
|
}
|
|
|
|
const queryData = getLocationParameterType(query);
|
|
|
|
const result = await getResults(queryData, limit);
|
|
|
|
return result;
|
|
});
|