You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

database.ts 1.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import * as sqlite from "sqlite3";
  2. import * as path from "path";
  3. const db = new sqlite.Database(path.resolve("./queue.sqlite"));
  4. const run = <T>(sql: string, params: unknown[]) => {
  5. return new Promise<T[]>((resolve, reject) => {
  6. db.all(sql, ...params, (err: unknown, rows: T[]) => {
  7. if (err) {
  8. return reject(err);
  9. }
  10. resolve(rows);
  11. });
  12. });
  13. }
  14. export async function setup(){
  15. await run(`
  16. CREATE TABLE IF NOT EXISTS queue (
  17. id SERIAL PRIMARY KEY,
  18. url TEXT NOT NULL,
  19. ip TEXT NOT NULL
  20. );
  21. `, []);
  22. }
  23. export const enqueue = async (url: string, ip: string) => {
  24. const [{ count }] = await run<{ count: number }>(`
  25. SELECT count(*) as count
  26. FROM queue
  27. WHERE ip = ?;
  28. `, [ip]);
  29. if (count > 3) {
  30. return false;
  31. }
  32. await run(`
  33. INSERT INTO queue (url, ip)
  34. VALUES (?, ?);
  35. `, [url, ip]);
  36. const [{ count: queueLength }] = await run<{ count: number }>(`
  37. SELECT count(*) as count
  38. FROM queue;
  39. `, [])
  40. return queueLength;
  41. }
  42. export const dequeue = async () => {
  43. const request = await run<{ url: string, ip: string }>(`
  44. SELECT url, ip
  45. FROM queue
  46. ORDER BY id ASC
  47. LIMIT 1;
  48. `, []);
  49. if (request.length === 0) {
  50. return undefined;
  51. }
  52. const [{ url, ip }] = request;
  53. // Delete based off of url and ip in case there are duplicates
  54. await run(`
  55. DELETE FROM queue
  56. WHERE url = ? AND ip = ?;
  57. `, [url, ip]);
  58. return url;
  59. }