db.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import { DatabaseSync } from "node:sqlite";
  2. function prepareDB(tableName: string) {
  3. const db = new DatabaseSync("data/postdown.db");
  4. switch (tableName) {
  5. case "User":
  6. db.exec(`
  7. CREATE TABLE IF NOT EXISTS user (
  8. id INTEGER PRIMARY KEY AUTOINCREMENT,
  9. name VARCHAR(128),
  10. email VARCHAR(128),
  11. password TEXT,
  12. created DATETIME DEFAULT CURRENT_TIMESTAMP,
  13. updated DATETIME,
  14. UNIQUE(name)
  15. )
  16. `);
  17. break;
  18. case "Token":
  19. db.exec(`
  20. CREATE TABLE IF NOT EXISTS token (
  21. id INTEGER PRIMARY KEY AUTOINCREMENT,
  22. user_id INTEGER,
  23. token VARCHAR(128),
  24. created DATETIME DEFAULT CURRENT_TIMESTAMP,
  25. updated DATETIME
  26. )
  27. `);
  28. break;
  29. case "Post":
  30. db.exec(`
  31. CREATE TABLE IF NOT EXISTS post (
  32. id VARCHAR(64) PRIMARY KEY,
  33. user_id INTEGER,
  34. title VARCHAR(256),
  35. content TEXT,
  36. shared BOOLEAN,
  37. created DATETIME DEFAULT CURRENT_TIMESTAMP,
  38. updated DATETIME
  39. )
  40. `);
  41. }
  42. return db;
  43. }
  44. export function find(
  45. tableName: string,
  46. queryObject: { [key: string]: string | number | boolean },
  47. targetKeys: string[] = [],
  48. limit?: number,
  49. ) {
  50. const db = prepareDB(tableName);
  51. const findQuery = db.prepare(
  52. `SELECT ${
  53. targetKeys.length > 0 ? targetKeys.join(", ") : "*"
  54. } FROM ${tableName.toLowerCase()} WHERE ${
  55. Object.keys(queryObject)
  56. .map((queryKey) => `${queryKey} = ?`)
  57. .join(" AND ")
  58. } ORDER BY updated DESC ${limit ? ` LIMIT ${limit}` : ""}`,
  59. );
  60. try {
  61. return findQuery.all(
  62. ...Object.values(queryObject).map((v) => v.toString()),
  63. );
  64. } catch (e) {
  65. console.error("Find error:", e);
  66. return [];
  67. } finally {
  68. db.close();
  69. }
  70. }
  71. export function insert(
  72. tableName: string,
  73. userInsertObject: { [key: string]: string | number | boolean },
  74. ) {
  75. const db = prepareDB(tableName);
  76. const insertObject = {
  77. ...userInsertObject,
  78. updated: new Date().toISOString().slice(0, 19).replace("T", " "),
  79. };
  80. const insertQuery = db.prepare(
  81. `INSERT INTO ${tableName.toLowerCase()} (${
  82. Object.keys(insertObject).join(
  83. ", ",
  84. )
  85. }) VALUES (${
  86. Object.keys(insertObject)
  87. .map(() => "?")
  88. .join(", ")
  89. })`,
  90. );
  91. try {
  92. insertQuery.run(...Object.values(insertObject).map((v) => v.toString()));
  93. return find(tableName, userInsertObject, ["id"], 1);
  94. } catch (e) {
  95. console.error("Insert error:", e);
  96. return [];
  97. } finally {
  98. db.close();
  99. }
  100. }
  101. export function update(
  102. tableName: string,
  103. id: number | string,
  104. userUpdateObject: { [key: string]: string | number | boolean },
  105. ) {
  106. const db = prepareDB(tableName);
  107. const updateObject = {
  108. ...userUpdateObject,
  109. updated: new Date().toISOString().slice(0, 19).replace("T", " "),
  110. };
  111. const updateQuery = db.prepare(
  112. `UPDATE ${tableName.toLowerCase()} SET ${
  113. Object.keys(updateObject)
  114. .map((updateKey) => `${updateKey} = ?`)
  115. .join(", ")
  116. } WHERE id = ?`,
  117. );
  118. try {
  119. updateQuery.run(
  120. ...Object.values(updateObject).map((v) => v.toString()),
  121. id,
  122. );
  123. return find(tableName, userUpdateObject, ["id"], 1);
  124. } catch (e) {
  125. console.error("Insert error:", e);
  126. return [];
  127. } finally {
  128. db.close();
  129. }
  130. }
  131. export function del(
  132. tableName: string,
  133. queryObject: { [key: string]: string | number | boolean },
  134. ) {
  135. const db = prepareDB(tableName);
  136. const deleteQuery = db.prepare(
  137. `DELETE FROM ${tableName.toLowerCase()} WHERE ${
  138. Object.keys(queryObject)
  139. .map((queryKey) => `${queryKey} = ?`)
  140. .join(" AND ")
  141. }`,
  142. );
  143. try {
  144. deleteQuery.all(...Object.values(queryObject).map((v) => v.toString()));
  145. return true;
  146. } catch (e) {
  147. console.error("Delete error:", e);
  148. return false;
  149. } finally {
  150. db.close();
  151. }
  152. }