domain.queries.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. const redis = require("../redis");
  2. const utils = require("../utils");
  3. const knex = require("../knex");
  4. const env = require("../env");
  5. async function find(match) {
  6. if (match.address && env.REDIS_ENABLED) {
  7. const cachedDomain = await redis.client.get(redis.key.domain(match.address));
  8. if (cachedDomain) return JSON.parse(cachedDomain);
  9. }
  10. const domain = await knex("domains").where(match).first();
  11. if (domain && env.REDIS_ENABLED) {
  12. const key = redis.key.domain(domain.address);
  13. redis.client.set(key, JSON.stringify(domain), "EX", 60 * 15);
  14. }
  15. return domain;
  16. }
  17. function get(match) {
  18. return knex("domains").where(match);
  19. }
  20. async function add(params) {
  21. params.address = params.address.toLowerCase();
  22. const existingDomain = await knex("domains").where("address", params.address).first();
  23. let id = existingDomain?.id;
  24. const newDomain = {
  25. address: params.address,
  26. homepage: params.homepage,
  27. user_id: params.user_id,
  28. banned: !!params.banned,
  29. banned_by_id: params.banned_by_id
  30. };
  31. if (id) {
  32. await knex("domains").where("id", id).update({
  33. ...newDomain,
  34. updated_at: params.updated_at || utils.dateToUTC(new Date())
  35. });
  36. } else {
  37. // Mysql and sqlite don't support returning but return the inserted id by default
  38. const [createdDomain] = await knex("domains").insert(newDomain).returning("id");
  39. id = createdDomain.id;
  40. }
  41. // Query domain instead of using returning as sqlite and mysql don't support it
  42. const domain = await knex("domains").where("id", id).first();
  43. if (env.REDIS_ENABLED) {
  44. redis.remove.domain(domain);
  45. }
  46. return domain;
  47. }
  48. async function update(match, update) {
  49. await knex("domains")
  50. .where(match)
  51. .update({ ...update, updated_at: utils.dateToUTC(new Date()) });
  52. const domains = await knex("domains").select("*").where(match);
  53. if (env.REDIS_ENABLED) {
  54. domains.forEach(redis.remove.domain);
  55. }
  56. return domains;
  57. }
  58. function normalizeMatch(match) {
  59. const newMatch = { ...match };
  60. if (newMatch.address) {
  61. newMatch["domains.address"] = newMatch.address;
  62. delete newMatch.address;
  63. }
  64. if (newMatch.user_id) {
  65. newMatch["domains.user_id"] = newMatch.user_id;
  66. delete newMatch.user_id;
  67. }
  68. if (newMatch.uuid) {
  69. newMatch["domains.uuid"] = newMatch.uuid;
  70. delete newMatch.uuid;
  71. }
  72. if (newMatch.banned !== undefined) {
  73. newMatch["domains.banned"] = newMatch.banned;
  74. delete newMatch.banned;
  75. }
  76. return newMatch;
  77. }
  78. const selectable_admin = [
  79. "domains.id",
  80. "domains.address",
  81. "domains.homepage",
  82. "domains.banned",
  83. "domains.created_at",
  84. "domains.updated_at",
  85. "domains.user_id",
  86. "domains.uuid",
  87. "users.email as email",
  88. "links_count"
  89. ];
  90. async function getAdmin(match, params) {
  91. const query = knex("domains").select(...selectable_admin);
  92. Object.entries(normalizeMatch(match)).forEach(([key, value]) => {
  93. query.andWhere(key, ...(Array.isArray(value) ? value : [value]));
  94. });
  95. query
  96. .offset(params.skip)
  97. .limit(params.limit)
  98. .fromRaw("domains")
  99. .orderBy("domains.id", "desc")
  100. .groupBy(1)
  101. .groupBy("l.links_count")
  102. .groupBy("users.email");
  103. if (params?.user) {
  104. const id = parseInt(params?.user);
  105. if (Number.isNaN(id)) {
  106. query.andWhereILike("users.email", "%" + params.user + "%");
  107. } else {
  108. query.andWhere("domains.user_id", id);
  109. }
  110. }
  111. if (params?.search) {
  112. query.andWhereRaw(
  113. "concat_ws(' ', domains.address, domains.homepage) ILIKE '%' || ? || '%'",
  114. [params.search]
  115. );
  116. }
  117. if (params?.links !== undefined) {
  118. query.andWhere("links_count", params?.links ? "is not" : "is", null);
  119. }
  120. query.leftJoin(
  121. knex("links").select("domain_id").count("id as links_count").groupBy("domain_id").as("l"),
  122. "domains.id",
  123. "l.domain_id"
  124. );
  125. query.leftJoin("users", "domains.user_id", "users.id");
  126. return query;
  127. }
  128. async function totalAdmin(match, params) {
  129. const query = knex("domains");
  130. Object.entries(normalizeMatch(match)).forEach(([key, value]) => {
  131. query.andWhere(key, ...(Array.isArray(value) ? value : [value]));
  132. });
  133. if (params?.user) {
  134. const id = parseInt(params?.user);
  135. if (Number.isNaN(id)) {
  136. query.andWhereILike("users.email", "%" + params.user + "%");
  137. } else {
  138. query.andWhere("domains.user_id", id);
  139. }
  140. }
  141. if (params?.search) {
  142. query.andWhereILike("domains.address", "%" + params.search + "%");
  143. }
  144. if (params?.links !== undefined) {
  145. query.leftJoin(
  146. knex("links").select("domain_id").count("id as links_count").groupBy("domain_id").as("l"),
  147. "domains.id",
  148. "l.domain_id"
  149. );
  150. query.andWhere("links_count", params?.links ? "is not" : "is", null);
  151. }
  152. query.leftJoin("users", "domains.user_id", "users.id");
  153. query.count("domains.id");
  154. const [{ count }] = await query;
  155. return typeof count === "number" ? count : parseInt(count);
  156. }
  157. async function remove(domain) {
  158. const deletedDomain = await knex("domains").where("id", domain.id).delete();
  159. if (env.REDIS_ENABLED) {
  160. redis.remove.domain(domain);
  161. }
  162. return !!deletedDomain;
  163. }
  164. module.exports = {
  165. add,
  166. find,
  167. get,
  168. getAdmin,
  169. remove,
  170. totalAdmin,
  171. update,
  172. }