diff --git a/Cargo.lock b/Cargo.lock index 281f3958..b2028f8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1262,6 +1262,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derive-new" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_builder" version = "0.12.0" @@ -2200,6 +2211,7 @@ dependencies = [ "color-thief", "dashmap", "deadpool-redis", + "derive-new", "dotenvy", "env_logger", "flate2", diff --git a/Cargo.toml b/Cargo.toml index c7016e72..819d1484 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,5 +106,7 @@ woothee = "0.13.0" lettre = "0.10.4" +derive-new = "0.5.9" + [dev-dependencies] actix-http = "3.4.0" diff --git a/sqlx-data.json b/sqlx-data.json index 89f6051d..e69de29b 100644 --- a/sqlx-data.json +++ b/sqlx-data.json @@ -1,7189 +0,0 @@ -{ - "db": "PostgreSQL", - "009bce5eee6ed65d9dc0899a4e24da528507a3f00b7ec997fa9ccdd7599655b1": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8", - "Text" - ] - } - }, - "query": "\n SELECT m.id FROM organizations o\n INNER JOIN mods m ON m.organization_id = o.id\n WHERE (o.id = $1 AND $1 IS NOT NULL) OR (o.title = $2 AND $2 IS NOT NULL)\n " - }, - "010cafcafb6adc25b00e3c81d844736b0245e752a90334c58209d8a02536c800": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET moderation_message = NULL, moderation_message_body = NULL, queued = NOW()\n WHERE (id = $1)\n " - }, - "0244926b35b964da2b50ccf82aff001250a3751d2314707c4884066432aa4753": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "team_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "role", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "permissions", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "organization_permissions", - "ordinal": 5, - "type_info": "Int8" - }, - { - "name": "accepted", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "payouts_split", - "ordinal": 7, - "type_info": "Numeric" - }, - { - "name": "ordering", - "ordinal": 8, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - true, - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT tm.id, tm.team_id, tm.user_id, tm.role, tm.permissions, tm.organization_permissions, tm.accepted, tm.payouts_split, tm.ordering\n FROM mods m\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND user_id = $2 AND accepted = TRUE\n WHERE m.id = $1\n " - }, - "02843e787de72594e186a14734bd02099ca6d2f07dcc06da8d6d8a069638ca2a": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 1, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false - ], - "parameters": { - "Left": [ - "Text", - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT id, mod_id FROM versions\n WHERE ((version_number = $1 OR id = $3) AND mod_id = $2)\n " - }, - "03006da8781d9c07d564c6b406221cb0557623abe3242e79a21868482e6d9898": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Timestamptz", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET status = $1, date_published = $2\n WHERE (id = $3)\n " - }, - "04128dd06489004e0d0305bfd0f4ca5ee4b4a6b9f610de6e1b9ef9c8543cc025": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "SELECT id FROM users WHERE trolley_id = $1" - }, - "04345d9c23430267f755b1420520df91bd403524fd60ba1a94e3a239ea70cae7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET source_url = $1\n WHERE (id = $2)\n " - }, - "0461463e3e14f6c8ede5571a2905b8171e8caf4ebbd3ec844ef2cebd83980247": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM reports\n WHERE user_id = $1 OR reporter = $1\n " - }, - "0472045549758d8eef84592908c438d6222a26926f4b06865b84979fc92564ba": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Timestamptz" - ] - } - }, - "query": "\n UPDATE pats\n SET last_used = $2\n WHERE (id = $1)\n " - }, - "04e5ecb14c526000e9098efb65861f6125e6fcc88f39d6ad811ac8504d229de1": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET icon_url = NULL, color = NULL\n WHERE (id = $1)\n " - }, - "05047ef3c49f2b90f5d090f69f8e7f626843d9487d5e63a28e8efe28e27cb9ad": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "title", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "team_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "description", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "icon_url", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "color", - "ordinal": 5, - "type_info": "Int4" - } - ], - "nullable": [ - false, - false, - false, - false, - true, - true - ], - "parameters": { - "Left": [ - "Int8Array", - "TextArray" - ] - } - }, - "query": "\n SELECT o.id, o.title, o.team_id, o.description, o.icon_url, o.color\n FROM organizations o\n WHERE o.id = ANY($1) OR o.title = ANY($2)\n GROUP BY o.id;\n " - }, - "05baeb26d9856218e5c6f8856a96788b2a7ac3536ff9412a50552cef1d561a1e": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4" - ] - } - }, - "query": "\n INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional)\n VALUES ($1, $2, FALSE)\n " - }, - "061a3e43df9464263aaf1555a27c1f4b6a0f381282f4fa75cc13b1d354857578": { - "describe": { - "columns": [ - { - "name": "pid", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "oid", - "ordinal": 1, - "type_info": "Int8" - } - ], - "nullable": [ - null, - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT m.id AS pid, NULL AS oid\n FROM mods m\n WHERE m.team_id = $1\n \n UNION ALL\n \n SELECT NULL AS pid, o.id AS oid\n FROM organizations o\n WHERE o.team_id = $1 \n " - }, - "06a92b638c77276f36185788748191e7731a2cce874ecca4af913d0d0412d223": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET downloads = $1\n WHERE (id = $2)\n " - }, - "07b692d2f89cdcc66da4e1a834f6fefe6a24c13c287490662585749b2b8baae3": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text", - "Int8" - ] - } - }, - "query": "\n UPDATE organizations\n SET title = LOWER($1)\n WHERE (id = $2)\n " - }, - "07ebc9dc82cd012cd4f5880b1eb3d82602c195a3e3ddd557103ee037aa6dad1c": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO mods_donations (joining_mod_id, joining_platform_id, url)\n VALUES ($1, $2, $3)\n " - }, - "08baa3d4e15821d791a1981a6abf653991dcc0901cea49156cd202d10ed2968c": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT id FROM users WHERE github_id = $1" - }, - "08f6bc80d18c171e54dd1db90e15569a02b526d708a9c918c90d79c764cb02fa": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - }, - { - "name": "category", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "icon", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "category_header", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "project_type", - "ordinal": 4, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - false, - false, - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT c.id id, c.category category, c.icon icon, c.header category_header, pt.name project_type\n FROM categories c\n INNER JOIN project_types pt ON c.project_type = pt.id\n ORDER BY c.ordering, c.category\n " - }, - "09f4fba5c0c26457a7415a2196d4f5a9b2c72662b92cae8c96dda9557a024df7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET email = $1, email_verified = FALSE\n WHERE (id = $2)\n " - }, - "0a1a470c12b84c7e171f0f51e8e541e9abe8bbee17fc441a5054e1dfd5607c05": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET name = $1\n WHERE (id = $2)\n " - }, - "0b79ae3825e05ae07058a0a9d02fb0bd68ce37f3c7cf0356d565c23520988816": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "version_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "url", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "filename", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "is_primary", - "ordinal": 5, - "type_info": "Bool" - }, - { - "name": "size", - "ordinal": 6, - "type_info": "Int4" - }, - { - "name": "file_type", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "hashes", - "ordinal": 8, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - true, - null - ], - "parameters": { - "Left": [ - "Text", - "ByteaArray" - ] - } - }, - "query": "\n SELECT f.id, f.version_id, v.mod_id, f.url, f.filename, f.is_primary, f.size, f.file_type,\n JSONB_AGG(DISTINCT jsonb_build_object('algorithm', h.algorithm, 'hash', encode(h.hash, 'escape'))) filter (where h.hash is not null) hashes\n FROM files f\n INNER JOIN versions v on v.id = f.version_id\n INNER JOIN hashes h on h.file_id = f.id\n WHERE h.algorithm = $1 AND h.hash = ANY($2)\n GROUP BY f.id, v.mod_id, v.date_published\n ORDER BY v.date_published\n " - }, - "0b9f174d86badae0d30e34b32130c7cee69926e37db95494ab08f025d19cdb7c": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "title", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "description", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "icon_url", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "color", - "ordinal": 4, - "type_info": "Int4" - }, - { - "name": "created", - "ordinal": 5, - "type_info": "Timestamptz" - }, - { - "name": "user_id", - "ordinal": 6, - "type_info": "Int8" - }, - { - "name": "updated", - "ordinal": 7, - "type_info": "Timestamptz" - }, - { - "name": "status", - "ordinal": 8, - "type_info": "Varchar" - }, - { - "name": "mods", - "ordinal": 9, - "type_info": "Int8Array" - } - ], - "nullable": [ - false, - false, - false, - true, - true, - false, - false, - false, - false, - null - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT c.id id, c.title title, c.description description,\n c.icon_url icon_url, c.color color, c.created created, c.user_id user_id,\n c.updated updated, c.status status,\n ARRAY_AGG(DISTINCT cm.mod_id) filter (where cm.mod_id is not null) mods\n FROM collections c\n LEFT JOIN collections_mods cm ON cm.collection_id = c.id\n WHERE c.id = ANY($1)\n GROUP BY c.id;\n " - }, - "0ba5a9f4d1381ed37a67b7dc90edf7e3ec86cae6c2860e5db1e53144d4654e58": { - "describe": { - "columns": [ - { - "name": "amount", - "ordinal": 0, - "type_info": "Numeric" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT SUM(pv.amount) amount\n FROM payouts_values pv\n WHERE pv.user_id = $1\n " - }, - "0c2addb0d7a87fa558821ff8e943bbb751fb2bdc22d1a5368f61cc7827586840": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Varchar", - "Varchar", - "Bool", - "Int4", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO files (id, version_id, url, filename, is_primary, size, file_type)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n " - }, - "0c6b7e51b0b9115d95b5dbb9bb88a3e266b78ae9375a90261503c2cccd5bdf1b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET organization_id = $1\n WHERE (id = $2)\n " - }, - "0eb293a353be47c61620922634cc339eda0e2422fcc602d7506c7cdf6152c928": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int4", - "Int8" - ] - } - }, - "query": "\n UPDATE organizations\n SET icon_url = $1, color = $2\n WHERE (id = $3)\n " - }, - "0f29bb5ba767ebd0669c860994e48e3cb2674f0d53f6c4ab85c79d46b04cbb40": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM mods WHERE id=$1)\n " - }, - "0fb1cca8a2a37107104244953371fe2f8a5e6edd57f4b325c5842c6571eb16b4": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM mod_follows mf WHERE mf.follower_id = $1 AND mf.mod_id = $2)\n " - }, - "10279b5a8383ba8e286f1bfb9a486e3f8b362c46cfc2647c90a83a10e5329569": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE threads\n SET show_in_mod_inbox = FALSE\n WHERE id = $1\n " - }, - "1209ffc1ffbea89f7060573275dc7325ac4d7b4885b6c1d1ec92998e6012e455": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Varchar" - ] - } - }, - "query": "\n UPDATE mods_gallery\n SET description = $2\n WHERE id = $1\n " - }, - "1220d15a56dbf823eaa452fbafa17442ab0568bc81a31fa38e16e3df3278e5f9": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM users WHERE id = $1)" - }, - "124fbf0544ea6989d6dc5e840405dbc76d7385276a38ad79d9093c53c73bbde2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET webhook_sent = TRUE\n WHERE id = $1\n " - }, - "127691940ca7e542e246dd2a1c9cb391041b30ddf0547d73b49c1dd9dc59d2ae": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n UPDATE notifications\n SET read = TRUE\n WHERE id = ANY($1)\n " - }, - "15fac93c76e72348b50f526e1acb183521d94be335ad8b9dfeb0398d4a8a2fc4": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Int4", - "Timestamptz", - "Int8", - "Varchar", - "Int8", - "Int8", - "Int8", - "Int8" - ] - } - }, - "query": "\n INSERT INTO uploaded_images (\n id, url, size, created, owner_id, context, mod_id, version_id, thread_message_id, report_id\n )\n VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8, $9, $10\n );\n " - }, - "16049957962ded08751d5a4ddce2ffac17ecd486f61210c51a952508425d83e6": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET changelog = $1\n WHERE (id = $2)\n " - }, - "164e5168aabe47d64f99ea851392c9d8479022cff360a610f185c342a24e88d8": { - "describe": { - "columns": [ - { - "name": "mod_id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT mod_id FROM versions WHERE id = $1\n " - }, - "165a4e679a0063dbf20832f298b4af3bb350f2e7128b0a91d6c1b8a25e56b0f6": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM reports WHERE id = $1 AND reporter = $2)" - }, - "166d93a7d4ac629444eadcd51d793490220bbf1e503bf85ec97b37500c8f74aa": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM sessions WHERE id = $1\n " - }, - "177716d2b04fd2a2b63b2e14c8ffdfa554d84254b14053496c118dec24bf5049": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "TextArray" - ] - } - }, - "query": "\n UPDATE mods\n SET game_versions = (\n SELECT COALESCE(ARRAY_AGG(DISTINCT gv.version) filter (where gv.version is not null), array[]::varchar[])\n FROM versions v\n INNER JOIN game_versions_versions gvv ON v.id = gvv.joining_version_id\n INNER JOIN game_versions gv on gvv.game_version_id = gv.id\n WHERE v.mod_id = mods.id AND v.status != ALL($2)\n )\n WHERE id = $1\n " - }, - "1931ff3846345c0af4e15c3a84dcbfc7c9cbb92c98d2e73634f611a1e5358c7a": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM threads WHERE id=$1)" - }, - "196c8ac2228e199f23eaf980f7ea15b37f76e66bb81da1115a754aad0be756e4": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Numeric", - "Timestamptz" - ] - } - }, - "query": "\n INSERT INTO payouts_values (user_id, mod_id, amount, created)\n VALUES ($1, $2, $3, $4)\n " - }, - "19c7498a01f51b8220245a53490916191a153fa1fe14404d39ab2980e3386058": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET organization_id = NULL\n WHERE (id = $1)\n " - }, - "19dc22c4d6d14222f8e8bace74c2961761c53b7375460ade15af921754d5d7da": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET license = $1\n WHERE (id = $2)\n " - }, - "1ab781d26c93aa74bf90b78b74b99e50004d25d42d56b734e5e83f2333d0c0d2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET avatar_url = $1\n WHERE (id = $2)\n " - }, - "1abc74fe1da85e031edbc896797991337b57d2c47a8a978f9b9f34b20bf8f410": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE collections\n SET icon_url = NULL, color = NULL\n WHERE (id = $1)\n " - }, - "1cefe4924d3c1f491739858ce844a22903d2dbe26f255219299f1833a10ce3d7": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8", - "TextArray" - ] - } - }, - "query": "\n SELECT id FROM mods TABLESAMPLE SYSTEM_ROWS($1) WHERE status = ANY($2)\n " - }, - "1d6a53187082ad9a57294d9f1c13d66131ccc3d4a0cf59d42346474196ea50f8": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "url", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "size", - "ordinal": 2, - "type_info": "Int4" - }, - { - "name": "created", - "ordinal": 3, - "type_info": "Timestamptz" - }, - { - "name": "owner_id", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "context", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "mod_id", - "ordinal": 6, - "type_info": "Int8" - }, - { - "name": "version_id", - "ordinal": 7, - "type_info": "Int8" - }, - { - "name": "thread_message_id", - "ordinal": 8, - "type_info": "Int8" - }, - { - "name": "report_id", - "ordinal": 9, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - true, - true, - true - ], - "parameters": { - "Left": [ - "Text", - "Int8", - "Int8", - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT id, url, size, created, owner_id, context, mod_id, version_id, thread_message_id, report_id\n FROM uploaded_images\n WHERE context = $1\n AND (mod_id = $2 OR ($2 IS NULL AND mod_id IS NULL))\n AND (version_id = $3 OR ($3 IS NULL AND version_id IS NULL))\n AND (thread_message_id = $4 OR ($4 IS NULL AND thread_message_id IS NULL))\n AND (report_id = $5 OR ($5 IS NULL AND report_id IS NULL))\n GROUP BY id\n " - }, - "1d6f3e926fc4a27c5af172f672b7f825f9f5fe2d538b06337ef182ab1a553398": { - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Varchar" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT name FROM project_types pt\n INNER JOIN mods ON mods.project_type = pt.id\n WHERE mods.id = $1\n " - }, - "1db6be78a74ff04c52ee105e0df30acf5bbf18f1de328980bb7f3da7f5f6569e": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM side_types\n WHERE name = $1\n " - }, - "1ffce9b2d5c9fa6c8b9abce4bad9f9419c44ad6367b7463b979c91b9b5b4fea1": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM versions WHERE id=$1)" - }, - "2007ac2b16a1d3d8fd053d962ba8548613535255fa197059e86959adf372948d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Jsonb" - ] - } - }, - "query": "\n UPDATE threads_messages\n SET body = $2\n WHERE id = $1\n " - }, - "21d20e5f09cb0729dc16c8609c35cec5a913f3172b53b8ae05da0096a33b4b64": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT id\n FROM pats\n WHERE user_id = $1\n ORDER BY created DESC\n " - }, - "21ef50f46b7b3e62b91e7d067c1cb33806e14c33bb76d63c2711f822c44261f6": { - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Varchar" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT name FROM project_types pt\n INNER JOIN mods ON mods.project_type = pt.id\n WHERE mods.id = $1\n " - }, - "220e59ae72edef546e3c7682ae91336bfba3e4230add1543910d80e846e0ad95": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT m.id FROM mods m\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.accepted = TRUE\n WHERE tm.user_id = $1\n ORDER BY m.downloads DESC\n " - }, - "2265be690ec4c6b03fd142bb8b81a5ebec67d09a08c05e9dba122f5acf2fc98a": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Timestamptz" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM payouts_values WHERE created = $1)" - }, - "232d7d0319c20dd5fff29331b067d6c6373bcff761a77958a2bb5f59068a83a5": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE team_members\n SET permissions = $1\n WHERE (team_id = $2 AND user_id = $3)\n " - }, - "25131559cb73a088000ab6379a769233440ade6c7511542da410065190d203fc": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM loaders\n WHERE loader = $1\n " - }, - "294f264382ad55475b51776cd5d306c4867e8e6966ab79921bba69dc023f8337": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM threads_members\n WHERE thread_id = $1\n " - }, - "299b8ea6e7a0048fa389cc4432715dc2a09e227d2f08e91167a43372a7ac6e35": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods_categories\n WHERE joining_mod_id = $1 AND is_additional = FALSE\n " - }, - "29e171bd746ac5dc1fabae4c9f81c3d1df4e69c860b7d0f6a907377664199217": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT id FROM reports\n WHERE closed = FALSE\n ORDER BY created ASC\n LIMIT $1;\n " - }, - "29e657d26f0fb24a766f5b5eb6a94d01d1616884d8ca10e91536e974d5b585a6": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n INSERT INTO loaders_versions (loader_id, version_id)\n VALUES ($1, $2)\n " - }, - "29fcff0f1d36bd1a9e0c8c4005209308f0c5f383e4e52ed8c6b989994ead32df": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE team_members\n SET ordering = $1\n WHERE (team_id = $2 AND user_id = $3)\n " - }, - "2a043ce990f4a31c1a3e5c836af515027eaf1ff1bbf08310fd215d0e96c2cdb3": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM uploaded_images\n WHERE id = $1\n " - }, - "2b8dafe9c3df9fd25235a13868e8e7607decfbe96a413cc576919a1fb510f269": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET discord_url = $1\n WHERE (id = $2)\n " - }, - "2bfde0471537cbdadd768006ff616e7513703971f9d60211106933d3eb759ad2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM team_members\n WHERE user_id = $1\n " - }, - "2d460f25461e95c744c835af5d67f8a7dd2438a46e3033611dfc0edd74fb9180": { - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "TextArray", - "TextArray" - ] - } - }, - "query": "\n SELECT COUNT(v.id)\n FROM versions v\n INNER JOIN mods m on v.mod_id = m.id AND m.status = ANY($1)\n WHERE v.status = ANY($2)\n " - }, - "2d68489b978c7a19bbea6a9736d23ca253f4038c0e3e060720d669825073b242": { - "describe": { - "columns": [ - { - "name": "code", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT code FROM user_backup_codes\n WHERE user_id = $1\n " - }, - "2df7a4dd792736be89c9da00c039ad7e271f79f4c756daac79ce5622ccb50db2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar" - ] - } - }, - "query": "\n UPDATE users\n SET google_id = $2\n WHERE (id = $1)\n " - }, - "2e14706127d9822d5a0d7ada02425d224805637d03eda1343e12111f7deba443": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods_categories\n WHERE joining_mod_id = $1\n " - }, - "2e5ddc7876d8041fec781893027f84b49b5794c85fa442296c35156d0a72464a": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Timestamptz", - "Int8", - "Int8", - "Int8", - "Varchar", - "Int8", - "Varchar", - "Bool", - "Text" - ] - } - }, - "query": "\n INSERT INTO users (\n id, username, name, email,\n avatar_url, bio, created,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7,\n $8, $9, $10, $11, $12, $13,\n $14, $15\n )\n " - }, - "2f4a620f954c7488e8bdb94a3d6968cec6d1332942b9e9f60925d14a8c2040f7": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8", - "Text" - ] - } - }, - "query": "\n SELECT m.id FROM mods m\n INNER JOIN team_members tm ON tm.team_id = m.team_id\n WHERE tm.user_id = $1 AND tm.role = $2\n " - }, - "304aaf99f8909f8315b57fb42b4320de66e7abb2fe1e7bdd19d8c4fd7d5b06be": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM users\n WHERE email = $1\n " - }, - "320d73cd900a6e00f0e74b7a8c34a7658d16034b01a35558cb42fa9c16185eb5": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "author_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "thread_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "body", - "ordinal": 3, - "type_info": "Jsonb" - }, - { - "name": "created", - "ordinal": 4, - "type_info": "Timestamptz" - } - ], - "nullable": [ - false, - true, - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT tm.id, tm.author_id, tm.thread_id, tm.body, tm.created\n FROM threads_messages tm\n WHERE tm.id = ANY($1)\n " - }, - "332f1d23442b4a637d4bccf29363a7aa4da974a1b6c5752eb1b611da75030741": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM pats\n WHERE user_id = $1\n " - }, - "33a965c7dc615d3b701c05299889357db8dd36d378850625d2602ba471af4885": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET downloads = downloads + $1\n WHERE (id = $2)\n " - }, - "33b9f52f7c67bf6272d0ba90a25185238d12494c9526ab112a854799627a69d7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET email_verified = TRUE\n WHERE (id = $1)\n " - }, - "33fc96ac71cfa382991cfb153e89da1e9f43ebf5367c28b30c336b758222307b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM loaders_versions\n WHERE loaders_versions.version_id = $1\n " - }, - "34354792d062d1d4e4d80d28c1bbc3c9b0abe0c6fb03e0387f102903d2b397b5": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "SELECT id FROM users WHERE google_id = $1" - }, - "352185977065c9903c2504081ef7c400075807785d4b62fdb48d0a45ca560f51": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM versions WHERE id = $1)" - }, - "3533fb2c185019bd2f4e5a89499ac19fec99452146cc80405b32d961ec50e456": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE team_members\n SET organization_permissions = $1\n WHERE (team_id = $2 AND user_id = $3)\n " - }, - "371048e45dd74c855b84cdb8a6a565ccbef5ad166ec9511ab20621c336446da6": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET follows = follows - 1\n WHERE id = $1\n " - }, - "382753714620109f2ad1a4cacbb6f699732db321a2dcb1f9d83e57332e32357d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET trolley_account_status = NULL, trolley_id = NULL\n WHERE id = $1\n " - }, - "38429340be03cc5f539d9d14c156e6b6710051d2826b53a5ccfdbd231af964ca": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM collections WHERE id=$1)" - }, - "3af747b5543a5a9b10dcce0a1eb9c2a1926dd5a507fe0d8b7f52d8ccc7fcd0af": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Bool" - ] - } - }, - "query": "\n UPDATE mods_gallery\n SET featured = $2\n WHERE id = $1\n " - }, - "3baabc9f08401801fa290866888c540746fc50c1d79911f08f3322b605ce5c30": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text", - "Int8" - ] - } - }, - "query": "\n SELECT id FROM mods\n WHERE status = $1\n ORDER BY queued ASC\n LIMIT $2;\n " - }, - "3bdcbfa5abe43cc9b4f996f147277a7f6921cca00f82cad0ef5d85032c761a36": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n DELETE FROM mod_follows\n WHERE follower_id = $1 AND mod_id = $2\n " - }, - "3c061c1888cb14655288cdbb2dad22f6cb51d6be3736e8d8206f918a9a64aec7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Varchar" - ] - } - }, - "query": "\n UPDATE mods_gallery\n SET title = $2\n WHERE id = $1\n " - }, - "3c50c07cddcc936a60ff1583b36fe0682da965b4aaf4579d08e2fe5468e71a3d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM collections_mods\n WHERE mod_id = $1\n " - }, - "3d384766d179f804c17e03d1917da65cc6043f88971ddc3fd23ba3be00717dfc": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - }, - { - "name": "version_", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "type_", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "created", - "ordinal": 3, - "type_info": "Timestamptz" - }, - { - "name": "major", - "ordinal": 4, - "type_info": "Bool" - } - ], - "nullable": [ - false, - false, - false, - false, - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT gv.id id, gv.version version_, gv.type type_, gv.created created, gv.major FROM game_versions gv\n ORDER BY created DESC\n " - }, - "3d700aaeb0d5129ac8c297ee0542757435a50a35ec94582d9d6ce67aa5302291": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET title = $1\n WHERE (id = $2)\n " - }, - "3f2f05653552ce8c1be95ce0a922ab41f52f40f8ff6c91c6621481102c8f35e3": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n INSERT INTO game_versions_versions (game_version_id, joining_version_id)\n VALUES ($1, $2)\n " - }, - "3f525e05e94ccaea4abc059d54f48011517bd8997df0c7d42cc4caae62194ae6": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET trolley_id = $1, trolley_account_status = $2\n WHERE id = $3\n " - }, - "3fcfed18cbfb37866e0fa57a4e95efb326864f8219941d1b696add39ed333ad1": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods_categories\n WHERE joining_mod_id = $1 AND is_additional = TRUE\n " - }, - "40f7c5bec98fe3503d6bd6db2eae5a4edb8d5d6efda9b9dc124f344ae5c60e08": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods_categories\n WHERE joining_mod_id = $1 AND is_additional = TRUE\n " - }, - "4242d5d0a6d1d4f22172cdfb06ef47189b69b52e01d00ec2effe580b42eda717": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET password = $1\n WHERE (id = $2)\n " - }, - "4514723bdc1eb8a781215075bec51af1cc6fabe88a469338d5a59533eabf80c5": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "project_type", - "ordinal": 1, - "type_info": "Int4" - }, - { - "name": "title", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "description", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "downloads", - "ordinal": 4, - "type_info": "Int4" - }, - { - "name": "follows", - "ordinal": 5, - "type_info": "Int4" - }, - { - "name": "icon_url", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "published", - "ordinal": 7, - "type_info": "Timestamptz" - }, - { - "name": "approved", - "ordinal": 8, - "type_info": "Timestamptz" - }, - { - "name": "updated", - "ordinal": 9, - "type_info": "Timestamptz" - }, - { - "name": "team_id", - "ordinal": 10, - "type_info": "Int8" - }, - { - "name": "license", - "ordinal": 11, - "type_info": "Varchar" - }, - { - "name": "slug", - "ordinal": 12, - "type_info": "Varchar" - }, - { - "name": "status_name", - "ordinal": 13, - "type_info": "Varchar" - }, - { - "name": "color", - "ordinal": 14, - "type_info": "Int4" - }, - { - "name": "client_side_type", - "ordinal": 15, - "type_info": "Varchar" - }, - { - "name": "server_side_type", - "ordinal": 16, - "type_info": "Varchar" - }, - { - "name": "project_type_name", - "ordinal": 17, - "type_info": "Varchar" - }, - { - "name": "username", - "ordinal": 18, - "type_info": "Varchar" - }, - { - "name": "categories", - "ordinal": 19, - "type_info": "VarcharArray" - }, - { - "name": "additional_categories", - "ordinal": 20, - "type_info": "VarcharArray" - }, - { - "name": "loaders", - "ordinal": 21, - "type_info": "VarcharArray" - }, - { - "name": "versions", - "ordinal": 22, - "type_info": "VarcharArray" - }, - { - "name": "gallery", - "ordinal": 23, - "type_info": "VarcharArray" - }, - { - "name": "featured_gallery", - "ordinal": 24, - "type_info": "VarcharArray" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - true, - false, - false, - false, - true, - false, - true, - false, - false, - false, - false, - null, - null, - null, - null, - null, - null - ], - "parameters": { - "Left": [ - "TextArray", - "TextArray", - "Text" - ] - } - }, - "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.published published, m.approved approved, m.updated updated,\n m.team_id team_id, m.license license, m.slug slug, m.status status_name, m.color color,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, u.username username,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n ARRAY_AGG(DISTINCT lo.loader) filter (where lo.loader is not null) loaders,\n ARRAY_AGG(DISTINCT gv.version) filter (where gv.version is not null) versions,\n ARRAY_AGG(DISTINCT mg.image_url) filter (where mg.image_url is not null and mg.featured is false) gallery,\n ARRAY_AGG(DISTINCT mg.image_url) filter (where mg.image_url is not null and mg.featured is true) featured_gallery\n FROM mods m\n LEFT OUTER JOIN mods_categories mc ON joining_mod_id = m.id\n LEFT OUTER JOIN categories c ON mc.joining_category_id = c.id\n LEFT OUTER JOIN versions v ON v.mod_id = m.id AND v.status != ALL($1)\n LEFT OUTER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id\n LEFT OUTER JOIN game_versions gv ON gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv ON lv.version_id = v.id\n LEFT OUTER JOIN loaders lo ON lo.id = lv.loader_id\n LEFT OUTER JOIN mods_gallery mg ON mg.mod_id = m.id\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.role = $3 AND tm.accepted = TRUE\n INNER JOIN users u ON tm.user_id = u.id\n WHERE m.status = ANY($2)\n GROUP BY m.id, cs.id, ss.id, pt.id, u.id;\n " - }, - "4567790f0dc98ff20b596a33161d1f6ac8af73da67fe8c54192724626c6bf670": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods_donations\n WHERE joining_mod_id = $1\n " - }, - "45e3f7d3ae0396c0b0196ed959f9b60c57b7c57390758ddcc58fb2e0f276a426": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE uploaded_images\n SET thread_message_id = $1\n WHERE id = $2\n " - }, - "4838777a8ef4371f4f5bb4f4f038bb6d041455f0849a3972a5418d75165ae9c7": { - "describe": { - "columns": [ - { - "name": "dependency_id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "mod_dependency_id", - "ordinal": 2, - "type_info": "Int8" - } - ], - "nullable": [ - true, - null, - true - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT d.dependency_id, COALESCE(vd.mod_id, 0) mod_id, d.mod_dependency_id\n FROM versions v\n INNER JOIN dependencies d ON d.dependent_id = v.id\n LEFT JOIN versions vd ON d.dependency_id = vd.id\n WHERE v.mod_id = $1\n " - }, - "489913b3c32631fb329a3259cfe620d65053e2abf425a0d3f1bc01f1cdbdd73d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n INSERT INTO collections_mods (collection_id, mod_id)\n VALUES ($1, $2)\n ON CONFLICT DO NOTHING\n " - }, - "48dc011567c5d50ee734fd0bdd1f5d07d9ef066c485a9b34495120c9947489f8": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Numeric", - "Varchar", - "Text", - "Text" - ] - } - }, - "query": "\n INSERT INTO historical_payouts (user_id, amount, status, batch_id, payment_id)\n VALUES ($1, $2, $3, $4, $5)\n " - }, - "49813a96f007216072d69468aae705d73d5b85dcdd64a22060009b12d947ed5a": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Bool", - "Int8" - ] - } - }, - "query": "\n UPDATE threads\n SET show_in_mod_inbox = $1\n WHERE id = $2\n " - }, - "49a5d21a1454afc6383b78e468fd0decc75b9163e7286f34ceab22d563a0d3f7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "UPDATE mods\n SET downloads = downloads + 1\n WHERE (id = $1)" - }, - "4a54d350b4695c32a802675506e85b0506fc62a63ca0ee5f38890824301d6515": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET server_side = $1\n WHERE (id = $2)\n " - }, - "4c20de487460718c8c523fce28716900f5195d12397eba09a3c437d194ff2b2e": { - "describe": { - "columns": [ - { - "name": "mod_id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT mod_id FROM versions WHERE id = $1\n " - }, - "4c9e2190e2a68ffc093a69aaa1fc9384957138f57ac9cd85cbc6179613c13a08": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM mods WHERE id = $1)" - }, - "4d54032b02c860f4facec39eacb4548a0701d4505e7a80b4834650696df69c2b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "UPDATE versions\n SET downloads = downloads + 1\n WHERE (id = $1)" - }, - "4d752ee3f43a1bf34d71c4391c9232537e0941294951f383ea8fa61e9d83fc96": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4" - ] - } - }, - "query": "\n DELETE FROM mods_gallery\n WHERE id = $1\n " - }, - "4e9f9eafbfd705dfc94571018cb747245a98ea61bad3fae4b3ce284229d99955": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET description = $1\n WHERE (id = $2)\n " - }, - "4fb5bd341369b4beb6b4a88de296b608ea5441a96db9f7360fbdccceb4628202": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET slug = LOWER($1)\n WHERE (id = $2)\n " - }, - "507314fdcacaa3c7751738c9d0baee2b90aec719b6b203f922824eced5ea8369": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM game_versions_versions WHERE joining_version_id = $1\n " - }, - "50e65ff5df36ec59c5cf4470db908d7b04cf1ffb1640398ac518510178fd9a34": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Int8", - "Int8" - ] - } - }, - "query": "\n INSERT INTO threads (\n id, thread_type, mod_id, report_id\n )\n VALUES (\n $1, $2, $3, $4\n )\n " - }, - "51e53fa0cc848654300067d4f598da49a16f5ce3aa046d1b08628566b80ce88f": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM user_backup_codes\n WHERE user_id = $1\n " - }, - "5295fba2053675c8414c0b37a59943535b9a438a642ea1c68045e987f05ade13": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - }, - { - "name": "loader", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "icon", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "project_types", - "ordinal": 3, - "type_info": "VarcharArray" - } - ], - "nullable": [ - false, - false, - false, - null - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT l.id id, l.loader loader, l.icon icon,\n ARRAY_AGG(DISTINCT pt.name) filter (where pt.name is not null) project_types\n FROM loaders l\n LEFT OUTER JOIN loaders_project_types lpt ON joining_loader_id = l.id\n LEFT OUTER JOIN project_types pt ON lpt.joining_project_type_id = pt.id\n GROUP BY l.id;\n " - }, - "52d947ff389e17378ff6d978916a85c2d6e7ef3cd4f09f4d5f070a6c33619cd9": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM user_backup_codes\n WHERE user_id = $1\n " - }, - "536f628092168eead27519db013ec8a1510a06f27e699839bac9dc85d16d99c2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Varchar", - "Varchar", - "Timestamptz", - "Varchar", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO collections (\n id, user_id, title, description, \n created, icon_url, status\n )\n VALUES (\n $1, $2, $3, $4, \n $5, $6, $7\n )\n " - }, - "53a8966ac345cc334ad65ea907be81af74e90b1217696c7eedcf8a8e3fca736e": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET version_number = $1\n WHERE (id = $2)\n " - }, - "5627b3516fc7c3799154098a663b1586aac11b2dc736810f06630ee5d8a54946": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 1, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false - ], - "parameters": { - "Left": [ - "Int8Array", - "Int8" - ] - } - }, - "query": "\n SELECT c.id id, c.user_id user_id FROM collections c\n WHERE c.user_id = $2 AND c.id = ANY($1)\n " - }, - "5944eb30a2bc0381c4d15eb1cf6ccf6e146a54381f2da8ab224960430e951976": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT id FROM threads\n WHERE report_id = $1\n " - }, - "599df07263a2705e57fc70a7c4f5dc606e1730c281e3b573d2f2a2030bed04e0": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n DELETE FROM notifications\n WHERE id = ANY($1)\n " - }, - "59e95e832615c375753bfc9a56b07c02d916399adfa52fb11a79b8f7b56ecf8b": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "title", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "description", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "color", - "ordinal": 3, - "type_info": "Int4" - }, - { - "name": "icon_url", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "slug", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "client_side_type", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "server_side_type", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "project_type", - "ordinal": 8, - "type_info": "Varchar" - }, - { - "name": "username", - "ordinal": 9, - "type_info": "Varchar" - }, - { - "name": "avatar_url", - "ordinal": 10, - "type_info": "Varchar" - }, - { - "name": "categories", - "ordinal": 11, - "type_info": "VarcharArray" - }, - { - "name": "loaders", - "ordinal": 12, - "type_info": "VarcharArray" - }, - { - "name": "versions", - "ordinal": 13, - "type_info": "Jsonb" - }, - { - "name": "gallery", - "ordinal": 14, - "type_info": "VarcharArray" - }, - { - "name": "featured_gallery", - "ordinal": 15, - "type_info": "VarcharArray" - } - ], - "nullable": [ - false, - false, - false, - true, - true, - true, - false, - false, - false, - false, - true, - null, - null, - null, - null, - null - ], - "parameters": { - "Left": [ - "Int8", - "TextArray", - "Text" - ] - } - }, - "query": "\n SELECT m.id id, m.title title, m.description description, m.color color,\n m.icon_url icon_url, m.slug slug, cs.name client_side_type, ss.name server_side_type,\n pt.name project_type, u.username username, u.avatar_url avatar_url,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null) categories,\n ARRAY_AGG(DISTINCT lo.loader) filter (where lo.loader is not null) loaders,\n JSONB_AGG(DISTINCT jsonb_build_object('id', gv.id, 'version', gv.version, 'type', gv.type, 'created', gv.created, 'major', gv.major)) filter (where gv.version is not null) versions,\n ARRAY_AGG(DISTINCT mg.image_url) filter (where mg.image_url is not null and mg.featured is false) gallery,\n ARRAY_AGG(DISTINCT mg.image_url) filter (where mg.image_url is not null and mg.featured is true) featured_gallery\n FROM mods m\n LEFT OUTER JOIN mods_categories mc ON joining_mod_id = m.id AND mc.is_additional = FALSE\n LEFT OUTER JOIN categories c ON mc.joining_category_id = c.id\n LEFT OUTER JOIN versions v ON v.mod_id = m.id AND v.status != ALL($2)\n LEFT OUTER JOIN game_versions_versions gvv ON gvv.joining_version_id = v.id\n LEFT OUTER JOIN game_versions gv ON gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv ON lv.version_id = v.id\n LEFT OUTER JOIN loaders lo ON lo.id = lv.loader_id\n LEFT OUTER JOIN mods_gallery mg ON mg.mod_id = m.id\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.role = $3 AND tm.accepted = TRUE\n INNER JOIN users u ON tm.user_id = u.id\n WHERE m.id = $1\n GROUP BY m.id, cs.id, ss.id, pt.id, u.id;\n " - }, - "5a13a79ebb1ab975f88b58e6deaba9685fe16e242c0fa4a5eea54f12f9448e6b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM reports\n WHERE version_id = $1\n " - }, - "5c3b340d278c356b6bc2cd7110e5093a7d1ad982ae0f468f8fff7c54e4e6603a": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM project_types\n WHERE name = $1\n " - }, - "5c4262689205aafdd97a74bee0003f39eef0a34c97f97a939c14fb8fe349f7eb": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE files\n SET is_primary = TRUE\n WHERE (id = $1)\n " - }, - "5c5cac91f61b0cd98d2d986e2d22e5a6b220bdd39f98520385f4ea84b3ffeeed": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET status = $1\n WHERE (id = $2)\n " - }, - "5c7bc2b59e5bcbe50e556cf28fb7a20de645752beef330b6779ec256f33e666a": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "url", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "size", - "ordinal": 2, - "type_info": "Int4" - }, - { - "name": "created", - "ordinal": 3, - "type_info": "Timestamptz" - }, - { - "name": "owner_id", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "context", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "mod_id", - "ordinal": 6, - "type_info": "Int8" - }, - { - "name": "version_id", - "ordinal": 7, - "type_info": "Int8" - }, - { - "name": "thread_message_id", - "ordinal": 8, - "type_info": "Int8" - }, - { - "name": "report_id", - "ordinal": 9, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - true, - true, - true - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT id, url, size, created, owner_id, context, mod_id, version_id, thread_message_id, report_id\n FROM uploaded_images\n WHERE id = ANY($1)\n GROUP BY id;\n " - }, - "5ca43f2fddda27ad857f230a3427087f1e58150949adc6273156718730c10f69": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET role = $1\n WHERE (id = $2)\n " - }, - "5d0b9862547d0920a5fd5ccc3460c6bf28bc7c0b1b832274ada6ce5d48b705a9": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT id FROM users WHERE gitlab_id = $1" - }, - "5d7425cfa91e332bf7cc14aa5c300b997e941c49757606f6b906cb5e060d3179": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET updated = NOW()\n WHERE id = $1\n " - }, - "5dd9503c98266d44dfef73dda81f0051789280b78d1b0fb4de509ac6ccfcb86a": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT id FROM users WHERE steam_id = $1" - }, - "5eb2795d25d6d03e22564048c198d821cd5ff22eb4e39b9dd7f198c9113d4f87": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET name = $1\n WHERE (id = $2)\n " - }, - "5ee2dc5cda9bfc0395da5a4ebf234093e9b8135db5e4a0258b00fa16fb825faa": { - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Varchar" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT name FROM project_types\n " - }, - "5f2d1161981df3d0fd1588580015525db13b06266314448b7fa400d298920c86": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n UPDATE mods_gallery\n SET ordering = $2\n WHERE id = $1\n " - }, - "5f94e9e767ec4be7f9136b991b4a29373dbe48feb2f61281e3212721095ed675": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Int8", - "Int8", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO dependencies (dependent_id, dependency_type, dependency_id, mod_dependency_id, dependency_file_name)\n VALUES ($1, $2, $3, $4, $5)\n " - }, - "61a7f29e024bf2f1368370e3f6e8ef70317c7e8545b5b6d4235f21164948ba27": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Bool" - ] - } - }, - "query": "\n UPDATE mods_gallery\n SET featured = $2\n WHERE mod_id = $1\n " - }, - "64d5e7cfb8472fbedcd06143db0db2f4c9677c42f73c540e85ccb5aee1a7b6f9": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Timestamptz", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar" - ] - } - }, - "query": "\n UPDATE sessions\n SET last_login = $2, city = $3, country = $4, ip = $5, os = $6, platform = $7, user_agent = $8\n WHERE (id = $1)\n " - }, - "65b5acdce6675d9c2abe636793dafef8ec915ddcc11a2735c66a49a48f314dd6": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "team_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "role", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "permissions", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "organization_permissions", - "ordinal": 5, - "type_info": "Int8" - }, - { - "name": "accepted", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "payouts_split", - "ordinal": 7, - "type_info": "Numeric" - }, - { - "name": "ordering", - "ordinal": 8, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - true, - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT tm.id, tm.team_id, tm.user_id, tm.role, tm.permissions, tm.organization_permissions, tm.accepted, tm.payouts_split, tm.ordering\n FROM organizations o\n INNER JOIN team_members tm ON tm.team_id = o.team_id AND user_id = $2 AND accepted = TRUE\n WHERE o.id = $1\n " - }, - "665e294e9737fd0299fc4639127d56811485dc8a5a4e08a4e7292044d8a2fb7a": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE reports\n SET body = $1\n WHERE (id = $2)\n " - }, - "66b06ddcd0a4cf01e716331befa393a12631fe6752a7d078bda06b24d50daae2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET requested_status = $1\n WHERE (id = $2)\n " - }, - "66d61a9077fd4fdf3c56e9cd6599095409ff3b46aad164210a1359a3154dbdb8": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM sessions WHERE id=$1)" - }, - "67d021f0776276081d3c50ca97afa6b78b98860bf929009e845e9c00a192e3b5": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM report_types\n WHERE name = $1\n " - }, - "680067ff64918882a3bff1438a6a70ca51a5dc52e48e47bbeb6e32d6739422d2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM notifications\n WHERE user_id = $1\n " - }, - "69b093cad9109ccf4779bfd969897f6b9ebc9d0d4230c958de4fa07435776349": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM sessions\n WHERE user_id = $1\n " - }, - "6a7b7704c2a0c52a70f5d881a1e6d3e8e77ddaa83ecc5688cd86bf327775fb76": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Bytea", - "Text" - ] - } - }, - "query": "\n SELECT f.id id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n WHERE h.algorithm = $2 AND h.hash = $1\n " - }, - "6b7958eac5f273af8f37c0c888594e106fe323cbb3b0c32868b02f869d30f33f": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "name", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "mod_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "version_id", - "ordinal": 3, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "body", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "reporter", - "ordinal": 6, - "type_info": "Int8" - }, - { - "name": "created", - "ordinal": 7, - "type_info": "Timestamptz" - }, - { - "name": "thread_id", - "ordinal": 8, - "type_info": "Int8" - }, - { - "name": "closed", - "ordinal": 9, - "type_info": "Bool" - } - ], - "nullable": [ - false, - false, - true, - true, - true, - false, - false, - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT r.id, rt.name, r.mod_id, r.version_id, r.user_id, r.body, r.reporter, r.created, t.id thread_id, r.closed\n FROM reports r\n INNER JOIN report_types rt ON rt.id = r.report_type_id\n INNER JOIN threads t ON t.report_id = r.id\n WHERE r.id = ANY($1)\n ORDER BY r.created DESC\n " - }, - "6b89c2b2557e304c2a3a02d7824327685f9be696254bf2370d0c995aafc6a2d8": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "TextArray" - ] - } - }, - "query": "\n UPDATE mods\n SET loaders = (\n SELECT COALESCE(ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null), array[]::varchar[])\n FROM versions v\n INNER JOIN loaders_versions lv ON lv.version_id = v.id\n INNER JOIN loaders l on lv.loader_id = l.id\n WHERE v.mod_id = mods.id AND v.status != ALL($2)\n )\n WHERE id = $1\n " - }, - "6c7aeb0db4a4fb3387c37b8d7aca6fdafaa637fd883a44416b56270aeebb7a01": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n INSERT INTO loaders_versions (loader_id, version_id)\n VALUES ($1, $2)\n " - }, - "6c8b8a2f11c0b4e7a5973547fe1611a0fa4ef366d5c8a91d9fb9a1360ea04d46": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Bytea", - "Text", - "Int8" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM hashes h\n INNER JOIN files f ON f.id = h.file_id\n INNER JOIN versions v ON v.id = f.version_id\n WHERE h.algorithm = $2 AND h.hash = $1 AND v.mod_id != $3)\n " - }, - "6d10ec782e422e868681827a6eb999edc6bf4fe8fa2b94d1f8970db2578c6db4": { - "describe": { - "columns": [ - { - "name": "created", - "ordinal": 0, - "type_info": "Timestamptz" - }, - { - "name": "amount", - "ordinal": 1, - "type_info": "Numeric" - }, - { - "name": "status", - "ordinal": 2, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT hp.created, hp.amount, hp.status\n FROM historical_payouts hp\n WHERE hp.user_id = $1\n ORDER BY hp.created DESC\n " - }, - "6d883ea05aead20f571a0f63bfd63f1d432717ec7a0fb9ab29e01fcb061b3afc": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE files\n SET is_primary = FALSE\n WHERE (version_id = $1)\n " - }, - "6db607d629be3047d53ff92bb82c07700595e8f4fcb7b602918540af4ae50d8b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM users\n WHERE id = $1\n " - }, - "6e07cc68675d0f583182eaa9f50853fa5996b9f83543fe8b6c2a073cf6a9cb5d": { - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "TextArray" - ] - } - }, - "query": "\n SELECT COUNT(id)\n FROM mods\n WHERE status = ANY($1)\n " - }, - "6ed8a0eadaa72fafc49538ed9be33c9621a763d2d4e1fbd1f541be50b48db4d2": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "team_id", - "ordinal": 1, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false - ], - "parameters": { - "Left": [ - "Int8Array", - "Int8Array", - "Int8" - ] - } - }, - "query": "\n SELECT m.id id, m.team_id team_id FROM team_members tm\n INNER JOIN mods m ON m.team_id = tm.team_id\n LEFT JOIN organizations o ON o.team_id = tm.team_id\n WHERE (tm.team_id = ANY($1) or o.id = ANY($2)) AND tm.user_id = $3\n " - }, - "6f594641f9633fbab31a57ebdbd33dd74f89e45252dfc2ae1cdbda549291b21b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mod_follows\n WHERE follower_id = $1\n " - }, - "6fbff950c4c996976a29898b120b9b8b562f25729166c21d6f5ed45c240c71be": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM uploaded_images WHERE id=$1)" - }, - "70b510956a40583eef8c57dcced71c67f525eee455ae8b09e9b2403668068751": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n INSERT INTO threads_members (\n thread_id, user_id\n )\n VALUES (\n $1, $2\n )\n " - }, - "71abd207410d123f9a50345ddcddee335fea0d0cc6f28762713ee01a36aee8a0": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8Array", - "Int8" - ] - } - }, - "query": "\n SELECT m.id FROM mods m\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND user_id = $2\n WHERE m.id = ANY($1)\n " - }, - "72c75313688dfd88a659c5250c71b9899abd6186ab32a067a7d4b8a0846ebd18": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Varchar", - "Text", - "Timestamp" - ] - } - }, - "query": "\n INSERT INTO game_versions (version, type, created)\n VALUES ($1, COALESCE($2, 'other'), COALESCE($3, timezone('utc', now())))\n ON CONFLICT (version) DO UPDATE\n SET type = COALESCE($2, game_versions.type),\n created = COALESCE($3, game_versions.created)\n RETURNING id\n " - }, - "72d6b5f2f11d88981db82c7247c9e7e5ebfd8d34985a1a8209d6628e66490f37": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM categories\n WHERE category = $1\n " - }, - "73bdd6c9e7cd8c1ed582261aebdee0f8fd2734e712ef288a2608564c918009cb": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM versions WHERE id = $1\n " - }, - "73d77f11f97a9073f601119c6eb450ea08ae1d2df1a27ba9af1efa972ed9a836": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int4", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET icon_url = $1, color = $2\n WHERE (id = $3)\n " - }, - "742f20f422361971c21b72c629c57a6c3870d8d6c41577496907290db5994f12": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET badges = $1\n WHERE (id = $2)\n " - }, - "75a860ca8087536a9fcf932846341c8bd322d314231bb8acac124d1cea93270b": { - "describe": { - "columns": [ - { - "name": "mod_id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT mf.mod_id FROM mod_follows mf\n WHERE mf.follower_id = $1\n " - }, - "75dc7f592781a1414e5f489543b14cb94c5265ddb3abfb3dda965c8cf154b753": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar" - ] - } - }, - "query": "\n UPDATE files\n SET file_type = $2\n WHERE (id = $1)\n " - }, - "7628dd456f01d307cc8647b36734b189a5f08dbaa9db78fe28f1de3d8f4757b7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE uploaded_images\n SET report_id = $1\n WHERE id = $2\n " - }, - "76db1c204139e18002e5751c3dcefff79791a1dd852b62d34fcf008151e8945a": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - }, - { - "name": "short", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "name", - "ordinal": 2, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT id, short, name FROM donation_platforms\n " - }, - "7711b7c651015510a101cc409fa6f5229ac93d7209df8bc158f4dd4442f611f2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM user_backup_codes\n WHERE user_id = $1\n " - }, - "77be410d0687b65b3554a35740fcf3c02418c5897856000716a35c02eed43d5a": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Int8", - "Text", - "Varchar", - "Int4" - ] - } - }, - "query": "\n INSERT INTO organizations (id, title, team_id, description, icon_url, color)\n VALUES ($1, $2, $3, $4, $5, $6)\n " - }, - "78699c6d2ca0f13f4609310df479903e8d5e0d2d4c2603df0333be7dc040a4ee": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM dependencies WHERE mod_dependency_id = $1\n " - }, - "7916fe4f04067324ae05598ec9dc6f97f18baf9eda30c64f32677158ada87478": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET monetization_status = $1\n WHERE (id = $2)\n " - }, - "796f057ea8eb5b01d3eedeee9840fb37464ea567f32871953fb07e14ed86af1c": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM team_members WHERE team_id = $1 AND user_id = $2)" - }, - "797cddf8f779025726a4a42c42985b8bc4c14094b76d9cd66dca20a7da3dec2a": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM mods m INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.user_id = $2 WHERE m.id = $1)" - }, - "79b896b1a8ddab285294638302976b75d0d915f36036383cc21bd2fc48d4502c": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM loaders_versions WHERE version_id = $1\n " - }, - "7ab21e7613dd88e97cf602e76bff62170c13ceef8104a4ce4cb2d101f8ce4f48": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Numeric", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET balance = balance + $1\n WHERE id = $2\n " - }, - "7af44414304c8be404d32daa3cadf99fc4ecf97b74aeb5d39c890b0f35a51f96": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT n.id FROM notifications n\n WHERE n.user_id = $1\n " - }, - "7b6b76f383adcbe2afbd2a2e87e66fd2a0d9d05b68b27823c1395e7cc3b8c0a2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE collections\n SET status = $1\n WHERE (id = $2)\n " - }, - "7c0cdacf0898155c94008a96a0b918550df4475b9e3362a926d4d00e001880c1": { - "describe": { - "columns": [ - { - "name": "amount", - "ordinal": 0, - "type_info": "Numeric" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT SUM(pv.amount) amount\n FROM payouts_values pv\n WHERE pv.user_id = $1 AND created > NOW() - '1 month'::interval\n " - }, - "7c61fee015231f0a97c25d24f2c6be24821e39e330ab82344ad3b985d0d2aaea": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM mods_gallery\n WHERE image_url = $1\n " - }, - "7cb691738c28e0d1f28c84ba2dbcfa21a6dbd859bcf0f565f90cd7ce2ea5aa1c": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4" - ] - } - }, - "query": "\n INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional)\n VALUES ($1, $2, FALSE)\n " - }, - "7e030d43f3412e7df63c970f873d0a73dd2deb9857aa6f201ec5eec628eb336c": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET github_id = $2\n WHERE (id = $1)\n " - }, - "81e2e17bfbaadbb3d25072cf6cb8e8d7b3842252b3c72fcbd24aadd2ad933472": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar" - ] - } - }, - "query": "\n UPDATE users\n SET microsoft_id = $2\n WHERE (id = $1)\n " - }, - "83d428e1c07d16e356ef26bdf1d707940b1683b5f631ded1f6674a081453d67b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET source_url = $1\n WHERE (id = $2)\n " - }, - "8422dcab178b4121d438a8fe4e365f527467c09d40a470a6c2cbdab71b04be4e": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM historical_payouts\n WHERE user_id = $1\n " - }, - "85463fa221147ee8d409fc92ed681fa27df683e7c80b8dd8616ae94dc1205c24": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET author_id = $1\n WHERE (author_id = $2)\n " - }, - "85b40877c48fc4f23039c1b556007f92056a015f160fe1059b0d3b13615af0fb": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Bool", - "Varchar", - "Varchar", - "Int8" - ] - } - }, - "query": "\n INSERT INTO mods_gallery (\n mod_id, image_url, featured, title, description, ordering\n )\n VALUES (\n $1, $2, $3, $4, $5, $6\n )\n " - }, - "85c6de008681d9fc9dc51b17330bed09204010813111e66a7ca84bc0e603f537": { - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Varchar" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT name FROM side_types\n " - }, - "868ee76d507cc9e94cd3c2e44770faff127e2b3c5f49b8100a9a37ac4d7b1f1d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET username = $1\n WHERE (id = $2)\n " - }, - "86b5f8c13cf232d55a6f5053db2727036fd3ccc7bd31b32aa443993d4815ab8f": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Timestamptz", - "Int8" - ] - } - }, - "query": "\n UPDATE pats\n SET expires = $1\n WHERE id = $2\n " - }, - "8abb317c85f48c7dd9ccf4a7b8fbc0b58ac73f7ae87ff2dfe67009a51089f784": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET wiki_url = $1\n WHERE (id = $2)\n " - }, - "8b99c759446f40e4ec9539cd368526ad9bcb1ddb266124c5f890e3b051c74c59": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods_gallery\n WHERE mod_id = $1\n " - }, - "8ba2b2c38958f1c542e514fc62ab4682f58b0b442ac1842d20625420698e34ec": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Text" - ] - } - }, - "query": "\n DELETE FROM team_members\n WHERE (team_id = $1 AND user_id = $2 AND NOT role = $3)\n " - }, - "8c93ad7aa81a0502494ff98dd6120c34d583d1a205b4c97ac54a7230b8c23765": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "team_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "role", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "permissions", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "organization_permissions", - "ordinal": 5, - "type_info": "Int8" - }, - { - "name": "accepted", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "payouts_split", - "ordinal": 7, - "type_info": "Numeric" - }, - { - "name": "ordering", - "ordinal": 8, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 9, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - true, - false, - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT tm.id, tm.team_id, tm.user_id, tm.role, tm.permissions, tm.organization_permissions, tm.accepted, tm.payouts_split, tm.ordering, v.mod_id \n FROM versions v\n INNER JOIN mods m ON m.id = v.mod_id\n INNER JOIN team_members tm ON tm.team_id = m.team_id AND tm.user_id = $2 AND tm.accepted = TRUE\n WHERE v.id = $1\n " - }, - "8f45a48700b8836f4ba8626b25b7be7f838d35d260430a46817729d9787e2013": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Bool", - "Text", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET email = $1, email_verified = $2, trolley_account_status = $3\n WHERE id = $4\n " - }, - "8f5e2a570cf35b2d158182bac37fd40bcec277bbdeddaece5efaa88600048a70": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE threads\n SET show_in_mod_inbox = FALSE\n WHERE id = $1\n " - }, - "912250d37f13a98a21165c72bfc1eaa8a85b9952dd6750c117dca7fbb1bb8962": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM threads_members\n WHERE user_id = $1\n " - }, - "91736b6bcc7a08c835cd3f3cea3a133ca42694df8fc3ce34b35d39bea6e1bba1": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE organizations\n SET icon_url = NULL, color = NULL\n WHERE (id = $1)\n " - }, - "92c00ebff25cfb0464947ea48faac417fabdb3cb3edd5ed45720598c7c12c689": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM payouts_values\n WHERE user_id = $1\n " - }, - "93c0fdb2bdc9c57602671d50108957654ede51e944944d4af59fe1ba1f6a336e": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "thread_type", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "mod_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "report_id", - "ordinal": 3, - "type_info": "Int8" - }, - { - "name": "show_in_mod_inbox", - "ordinal": 4, - "type_info": "Bool" - }, - { - "name": "members", - "ordinal": 5, - "type_info": "Int8Array" - }, - { - "name": "messages", - "ordinal": 6, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - true, - true, - false, - null, - null - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT t.id, t.thread_type, t.mod_id, t.report_id, t.show_in_mod_inbox,\n ARRAY_AGG(DISTINCT tm.user_id) filter (where tm.user_id is not null) members,\n JSONB_AGG(DISTINCT jsonb_build_object('id', tmsg.id, 'author_id', tmsg.author_id, 'thread_id', tmsg.thread_id, 'body', tmsg.body, 'created', tmsg.created)) filter (where tmsg.id is not null) messages\n FROM threads t\n LEFT OUTER JOIN threads_messages tmsg ON tmsg.thread_id = t.id\n LEFT OUTER JOIN threads_members tm ON tm.thread_id = t.id\n WHERE t.id = ANY($1)\n GROUP BY t.id\n " - }, - "9544cea57095a94109be5fef9a4737626a9003d58680943cdbffc7c9ada7877b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int4", - "Int8" - ] - } - }, - "query": "\n UPDATE collections\n SET icon_url = $1, color = $2\n WHERE (id = $3)\n " - }, - "957d0b3f6ad7d20f54548b05e82935cd18adc723f819fd071d8c97ec3885381a": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT m.id\n FROM mods m\n WHERE m.organization_id = $1\n " - }, - "95cb791af4ea4d5b959de9e451bb8875336db33238024812086b5237b4dac350": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM pats WHERE id = $1\n " - }, - "9608a95084c55d939d3f908f3dd7e53cb1c9455b5d53868993147bf6abc42ffb": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "title", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "team_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "description", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "icon_url", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "color", - "ordinal": 5, - "type_info": "Int4" - } - ], - "nullable": [ - false, - false, - false, - false, - true, - true - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT o.id, o.title, o.team_id, o.description, o.icon_url, o.color\n FROM organizations o\n LEFT JOIN mods m ON m.organization_id = o.id\n WHERE m.id = $1\n GROUP BY o.id;\n " - }, - "97690dda7edea8c985891cae5ad405f628ed81e333bc88df5493c928a4324d43": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM reports WHERE id=$1)" - }, - "9774f59e5d5ce6ba00ca7e3a4a81f80f78b908bdf664a4cdfad592a1b14c0d44": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Text" - ] - } - }, - "query": "\n UPDATE historical_payouts\n SET status = $1\n WHERE payment_id = $2\n " - }, - "99a1eac69d7f5a5139703df431e6a5c3012a90143a8c635f93632f04d0bc41d4": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET wiki_url = $1\n WHERE (id = $2)\n " - }, - "99e7779380ebae726051ba8e2810f37bee36f3fb36729c07ef11d0ac1b611d7e": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET totp_secret = NULL\n WHERE (id = $1)\n " - }, - "9aab2350d576fd934b0541d1f71f320ac939b44a179fee3d1638113cdb3ddfe7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO mods_donations (joining_mod_id, joining_platform_id, url)\n VALUES ($1, $2, $3)\n " - }, - "9bf8862af8f636c4ef77e8c9f1f5d31d4f2d3f5b73fb6e6ca8a09ad5224250c3": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET totp_secret = $1\n WHERE (id = $2)\n " - }, - "9c8f3f9503b5bb52e05bbc8a8eee7f640ab7d6b04a59ec111ce8b23e886911de": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM dependencies WHERE dependent_id = $1\n " - }, - "9d68929e384db6dc734afca0dfdfef15f103b6eccdf0d1d144180b0d7d4e3400": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM collections_mods\n WHERE collection_id = $1\n " - }, - "a0148ff25855202e7bb220b6a2bc9220a95e309fb0dae41d9a05afa86e6b33af": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods_categories\n WHERE joining_mod_id = $1 AND is_additional = FALSE\n " - }, - "a0c91184d5a02b986decac3c34e78b61451ff90e103bcf1ec46f8da3bbcc1ff2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n DELETE FROM notifications_actions\n WHERE notification_id = ANY($1)\n " - }, - "a11d613479d09dff5fcdc45ab7a0341fb1b4738f0ede71572d939ef0984bd65f": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET approved = NOW()\n WHERE id = $1 AND approved IS NULL\n " - }, - "a1a8aa7cc5d7967fbc64b979489222d9f5c154e21227f0edcbce1d96dddad3c6": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Text" - ] - } - }, - "query": "\n UPDATE team_members\n SET user_id = $1\n WHERE (user_id = $2 AND role = $3)\n " - }, - "a1ba3b5cc50b1eb24f5529e06be1439f4a313c4ea8845c2733db752e53f5ae1c": { - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "TextArray", - "TextArray" - ] - } - }, - "query": "\n SELECT COUNT(f.id) FROM files f\n INNER JOIN versions v on f.version_id = v.id AND v.status = ANY($2)\n INNER JOIN mods m on v.mod_id = m.id AND m.status = ANY($1)\n " - }, - "a440cb2567825c3cc540c9b0831ee840f6e2a6394e89a851b83fc78220594cf2": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Timestamptz", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET status = $1, approved = $2\n WHERE (id = $3)\n " - }, - "a48b717b74531dc457069ee811ec1adc1da195f00a42fff7f08667b139cd8fea": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n INSERT INTO user_backup_codes (\n user_id, code\n )\n VALUES (\n $1, $2\n )\n " - }, - "a62767e812783e8836a11b22878a4248123f3fe212a876e192f549acd6edcb39": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "author_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "version_name", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "version_number", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "changelog", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "date_published", - "ordinal": 6, - "type_info": "Timestamptz" - }, - { - "name": "downloads", - "ordinal": 7, - "type_info": "Int4" - }, - { - "name": "version_type", - "ordinal": 8, - "type_info": "Varchar" - }, - { - "name": "featured", - "ordinal": 9, - "type_info": "Bool" - }, - { - "name": "status", - "ordinal": 10, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 11, - "type_info": "Varchar" - }, - { - "name": "game_versions", - "ordinal": 12, - "type_info": "Jsonb" - }, - { - "name": "loaders", - "ordinal": 13, - "type_info": "VarcharArray" - }, - { - "name": "files", - "ordinal": 14, - "type_info": "Jsonb" - }, - { - "name": "hashes", - "ordinal": 15, - "type_info": "Jsonb" - }, - { - "name": "dependencies", - "ordinal": 16, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true, - null, - null, - null, - null, - null - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT v.id id, v.mod_id mod_id, v.author_id author_id, v.name version_name, v.version_number version_number,\n v.changelog changelog, v.date_published date_published, v.downloads downloads,\n v.version_type version_type, v.featured featured, v.status status, v.requested_status requested_status,\n JSONB_AGG(DISTINCT jsonb_build_object('version', gv.version, 'created', gv.created)) filter (where gv.version is not null) game_versions,\n ARRAY_AGG(DISTINCT l.loader) filter (where l.loader is not null) loaders,\n JSONB_AGG(DISTINCT jsonb_build_object('id', f.id, 'url', f.url, 'filename', f.filename, 'primary', f.is_primary, 'size', f.size, 'file_type', f.file_type)) filter (where f.id is not null) files,\n JSONB_AGG(DISTINCT jsonb_build_object('algorithm', h.algorithm, 'hash', encode(h.hash, 'escape'), 'file_id', h.file_id)) filter (where h.hash is not null) hashes,\n JSONB_AGG(DISTINCT jsonb_build_object('project_id', d.mod_dependency_id, 'version_id', d.dependency_id, 'dependency_type', d.dependency_type,'file_name', dependency_file_name)) filter (where d.dependency_type is not null) dependencies\n FROM versions v\n LEFT OUTER JOIN game_versions_versions gvv on v.id = gvv.joining_version_id\n LEFT OUTER JOIN game_versions gv on gvv.game_version_id = gv.id\n LEFT OUTER JOIN loaders_versions lv on v.id = lv.version_id\n LEFT OUTER JOIN loaders l on lv.loader_id = l.id\n LEFT OUTER JOIN files f on v.id = f.version_id\n LEFT OUTER JOIN hashes h on f.id = h.file_id\n LEFT OUTER JOIN dependencies d on v.id = d.dependent_id\n WHERE v.id = ANY($1)\n GROUP BY v.id\n ORDER BY v.date_published ASC;\n " - }, - "aaec611bae08eac41c163367dc508208178170de91165095405f1b41e47f5e7f": { - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "TextArray" - ] - } - }, - "query": "\n SELECT COUNT(DISTINCT u.id)\n FROM users u\n INNER JOIN team_members tm on u.id = tm.user_id AND tm.accepted = TRUE\n INNER JOIN mods m on tm.team_id = m.team_id AND m.status = ANY($1)\n " - }, - "aaec67a66b58dec36339c14000b319aed1b0ebb1324fc85e34d14c6430c26657": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text", - "Int4" - ] - } - }, - "query": "\n SELECT id FROM categories\n WHERE category = $1 AND project_type = $2\n " - }, - "abf790170e3a807ffe8b3a188da620c89e6398f38ff066220fdadffe8e7481c1": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM mods WHERE slug = LOWER($1))\n " - }, - "acbafe265c4b7a1c95b0494a0a03c8bd2cd778ae561ef5a662fa931ca26cf603": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods_donations\n WHERE joining_mod_id = $1\n " - }, - "ad27195af9964c34803343c22abcb9aa6b52f2d1a370550ed4fb68bce2297e71": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM pats WHERE id=$1)" - }, - "ae1686b8b566dd7ecc57c653c9313a4b324a2ec3a63aa6a44ed1d8ea7999b115": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [] - } - }, - "query": "\n DELETE FROM dependencies WHERE mod_dependency_id = NULL AND dependency_id = NULL AND dependency_file_name = NULL\n " - }, - "ae99bfaea7f127d24b714302c9b1d6894d06485b3c62a8921e6e82086a425ad4": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mod_follows\n WHERE mod_id = $1\n " - }, - "b0c29c51bd3ae5b93d487471a98ee9bbb43a4df468ba781852b137dd315b9608": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Jsonb", - "Int8" - ] - } - }, - "query": "\n INSERT INTO threads_messages (\n id, author_id, body, thread_id\n )\n VALUES (\n $1, $2, $3, $4\n )\n " - }, - "b139baf2b1424d1f38b9d80f3a33baf12195bcbac34bb779483e42315803b875": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "SELECT EXISTS(\n SELECT 1 \n FROM organizations o JOIN team_members tm ON tm.team_id = o.team_id\n WHERE o.id = $1 AND tm.user_id = $2\n )" - }, - "b1e77dbaf4b190ab361f4fa203c442e5905cef6c1a135011a59ebd6e2dc0a92a": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Numeric", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET balance = balance - $1\n WHERE id = $2\n " - }, - "b26cbb11458743ba0677f4ca24ceaff0f9766ddac4a076010c98cf086dd1d7af": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM organizations WHERE id=$1)\n " - }, - "b28b380e2d728c4733b9654e433b716114a215240845345b168d832e75769398": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM collections\n WHERE id = $1\n " - }, - "b297c97cd18785279cee369a1a269326ade765652ccf87405e6ee7dd3cbdaabf": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE pats\n SET name = $1\n WHERE id = $2\n " - }, - "b3345991457853c3f4c49dd68239bb23c3502d5c46008eb1b50233546a6ffa5d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE payouts_values\n SET mod_id = NULL\n WHERE (mod_id = $1)\n " - }, - "b36877d60945eaae76680770a5d28d2cbb26cfbb0ec94ecc8f0741f48178ec1c": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Varchar", - "Varchar", - "Varchar", - "Timestamptz", - "Int4", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Int4", - "Int4", - "Varchar", - "Varchar", - "Text", - "Int4", - "Int4", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO mods (\n id, team_id, title, description, body,\n published, downloads, icon_url, issues_url,\n source_url, wiki_url, status, requested_status, discord_url,\n client_side, server_side, license_url, license,\n slug, project_type, color, monetization_status\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7, $8, $9,\n $10, $11, $12, $13, $14,\n $15, $16, $17, $18,\n LOWER($19), $20, $21, $22\n )\n " - }, - "b641616b81b1cef2f95db719a492cc1f7aaba66da52efeadb05fc555611b174b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE collections\n SET description = $1\n WHERE (id = $2)\n " - }, - "b768d9db6c785d6a701324ea746794d33e94121403163a774b6ef775640fd3d3": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "payouts_split", - "ordinal": 2, - "type_info": "Numeric" - } - ], - "nullable": [ - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8Array", - "Text" - ] - } - }, - "query": "\n SELECT m.id id, tm.user_id user_id, tm.payouts_split payouts_split\n FROM mods m\n INNER JOIN team_members tm on m.team_id = tm.team_id AND tm.accepted = TRUE\n WHERE m.id = ANY($1) AND m.monetization_status = $2\n " - }, - "b903ac4e686ef85ba28d698c668da07860e7f276b261d8f2cebb74e73b094970": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM hashes\n WHERE EXISTS(\n SELECT 1 FROM files WHERE\n (files.version_id = $1) AND\n (hashes.file_id = files.id)\n )\n " - }, - "b9399840dbbf807a03d69b7fcb3bd479ef20920ab1e3c91706a1c2c7089f48e7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n INSERT INTO teams (id)\n VALUES ($1)\n " - }, - "b96ab39ab9624bfcdc8675107544307af9892504c4cbc40e4e7c40a1e4e83e14": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n INSERT INTO game_versions_versions (game_version_id, joining_version_id)\n VALUES ($1, $2)\n " - }, - "b971cecafab7046c5952447fd78a6e45856841256d812ce9ae3c07f903c5cc62": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n UPDATE mods\n SET status = requested_status\n WHERE status = $1 AND approved < CURRENT_DATE AND requested_status IS NOT NULL\n " - }, - "b99e906aa6ca18b9f3f111eae7bf0d360f42385ca99228a844387bf9456a6a31": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM reports WHERE id = $1\n " - }, - "ba2e730788fb7441a7f01f414eb79b6e73046af4123ac1756442eeb1a4f0f869": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n DELETE FROM notifications_actions\n WHERE notification_id = ANY($1)\n " - }, - "bad7cae347771e801976c26f2afaf33bda371051923b8f74a2f32a0ef5c65e57": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET discord_url = $1\n WHERE (id = $2)\n " - }, - "bc91841f9672608a28bd45a862919f2bd34fac0b3479e3b4b67a9f6bea2a562a": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET issues_url = $1\n WHERE (id = $2)\n " - }, - "bd0d1da185dc7d21ccbbfde86fc093ce9eda7dd7e07f7a53882d427010fd58ca": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM dependencies WHERE dependent_id = $1\n " - }, - "bee1abe8313d17a56d93b06a31240e338c3973bc7a7374799ced3df5e38d3134": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM game_versions_versions gvv\n WHERE gvv.joining_version_id = $1\n " - }, - "bf7f721664f5e0ed41adc41b5483037256635f28ff6c4e5d3cbcec4387f9c8ef": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM users WHERE id=$1)" - }, - "c100a3be0e1b7bf449576c4052d87494979cb89d194805a5ce9e928eef796ae9": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET license_url = $1\n WHERE (id = $2)\n " - }, - "c1a3f6dcef6110d6ea884670fb82bac14b98e922bb5673c048ccce7b7300539b": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM reports WHERE id = $1)\n " - }, - "c1fddbf97350871b79cb0c235b1f7488c6616b7c1dfbde76a712fd57e91ba158": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM game_versions\n WHERE version = $1\n " - }, - "c2564faa5f5a7d8aa485f4becde16ebf54d16f2dc41a70471e3b4fc896f11fd1": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET version_type = $1\n WHERE (id = $2)\n " - }, - "c3391aed338110205a170ba3032e54be0f2b753b5550d87d7b5ba3e17a57a202": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM reports\n WHERE mod_id = $1\n " - }, - "c3397fe8a9435d8c64283c8ae780a58b9f98e8c97c30e57d9c703619a6180917": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM teams\n WHERE id = $1\n " - }, - "c3f594d8d0ffcf5df1b36759cf3088bfaec496c5dfdbf496d3b05f0b122a5d0c": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4", - "Int8", - "Int8", - "Int8", - "Varchar", - "Int8" - ] - } - }, - "query": "\n INSERT INTO reports (\n id, report_type_id, mod_id, version_id, user_id,\n body, reporter\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7\n )\n " - }, - "c49cda8215982b699d7aee14614763c9b5b997489581293fc2ae3604697867fe": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "title", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "text", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "link", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "created", - "ordinal": 5, - "type_info": "Timestamptz" - }, - { - "name": "read", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "notification_type", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "body", - "ordinal": 8, - "type_info": "Jsonb" - }, - { - "name": "actions", - "ordinal": 9, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - true, - true, - true, - false, - false, - true, - true, - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT n.id, n.user_id, n.title, n.text, n.link, n.created, n.read, n.type notification_type, n.body,\n JSONB_AGG(DISTINCT jsonb_build_object('id', na.id, 'notification_id', na.notification_id, 'title', na.title, 'action_route_method', na.action_route_method, 'action_route', na.action_route)) filter (where na.id is not null) actions\n FROM notifications n\n LEFT OUTER JOIN notifications_actions na on n.id = na.notification_id\n WHERE n.user_id = $1\n GROUP BY n.id, n.user_id;\n " - }, - "c545a74e902c5c63bca1057b76e94b9547ee21fadbc61964f45837915d5f4608": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO mods_donations (\n joining_mod_id, joining_platform_id, url\n )\n VALUES (\n $1, $2, $3\n )\n " - }, - "c55d2132e3e6e92dd50457affab758623dca175dc27a2d3cd4aace9cfdecf789": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n INSERT INTO mod_follows (follower_id, mod_id)\n VALUES ($1, $2)\n " - }, - "c56dd77e35bf5372cd35ca981d248738b55f39d74428ed7d0c5ca2957a656eb6": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "SELECT id FROM users WHERE microsoft_id = $1" - }, - "c5d44333c62223bd3e68185d1fb3f95152fafec593da8d06c9b2b665218a02be": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int4", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET client_side = $1\n WHERE (id = $2)\n " - }, - "c6060a389343c9f35aea5d931518b85ab7c71b6ba74eae7b4b51d881f1798c6e": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8", - "Varchar", - "Int8", - "Int8", - "Bool", - "Numeric", - "Int8" - ] - } - }, - "query": "\n INSERT INTO team_members (id, team_id, user_id, role, permissions, organization_permissions, accepted, payouts_split, ordering)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)\n " - }, - "c8a27a122160a0896914c786deef9e8193eb240501d30d5ffb4129e2103efd3d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n UPDATE versions\n SET status = requested_status\n WHERE status = $1 AND date_published < CURRENT_DATE AND requested_status IS NOT NULL\n " - }, - "c8fde56e5d03eda085519b4407768de7ddf48cae18ce7138a97e8e8fba967e15": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8Array", - "Int8" - ] - } - }, - "query": "\n SELECT id FROM reports\n WHERE id = ANY($1) AND reporter = $2\n " - }, - "c920cc500f431a2b174d176c3a356d40295137fd87a5308d71aad173d18d9d91": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE uploaded_images\n SET version_id = $1\n WHERE id = $2\n " - }, - "c94faba99d486b11509fff59465b7cc71983551b035e936ce4d9776510afb514": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "session", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "created", - "ordinal": 3, - "type_info": "Timestamptz" - }, - { - "name": "last_login", - "ordinal": 4, - "type_info": "Timestamptz" - }, - { - "name": "expires", - "ordinal": 5, - "type_info": "Timestamptz" - }, - { - "name": "refresh_expires", - "ordinal": 6, - "type_info": "Timestamptz" - }, - { - "name": "os", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "platform", - "ordinal": 8, - "type_info": "Varchar" - }, - { - "name": "city", - "ordinal": 9, - "type_info": "Varchar" - }, - { - "name": "country", - "ordinal": 10, - "type_info": "Varchar" - }, - { - "name": "ip", - "ordinal": 11, - "type_info": "Varchar" - }, - { - "name": "user_agent", - "ordinal": 12, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - true, - true, - true, - true, - false, - false - ], - "parameters": { - "Left": [ - "Int8Array", - "TextArray" - ] - } - }, - "query": "\n SELECT id, user_id, session, created, last_login, expires, refresh_expires, os, platform,\n city, country, ip, user_agent\n FROM sessions\n WHERE id = ANY($1) OR session = ANY($2)\n ORDER BY created DESC\n " - }, - "cb57ae673f1a7e50cc319efddb9bdc82e2251596bcf85aea52e8def343e423b8": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Bytea" - ] - } - }, - "query": "\n INSERT INTO hashes (file_id, algorithm, hash)\n VALUES ($1, $2, $3)\n " - }, - "cb82bb6e22690fd5fee18bbc2975503371814ef1cbf95f32c195bfe7542b2b20": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8", - "Varchar", - "Int8", - "Int8", - "Bool" - ] - } - }, - "query": "\n INSERT INTO team_members (\n id, team_id, user_id, role, permissions, organization_permissions, accepted\n )\n VALUES (\n $1, $2, $3, $4, $5, $6, $7\n )\n " - }, - "ccce60dc60ca6c4ea1142ab6d0d81bdb1ee9ed97c992695324aec015e0e190bf": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n INSERT INTO collections_mods (collection_id, mod_id)\n VALUES ($1, $2)\n ON CONFLICT DO NOTHING\n " - }, - "ccd913bb2f3006ffe881ce2fc4ef1e721d18fe2eed6ac62627046c955129610c": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM files WHERE id=$1)" - }, - "cdd7f8f95c308d9474e214d584c03be0466214da1e157f6bc577b76dbef7df86": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM hashes\n WHERE file_id = $1\n " - }, - "cdf20036b29b61da40bf990c9ab04c509297a4d65bc9b136c9fb20f1e97e1149": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4" - ] - } - }, - "query": "\n INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional)\n VALUES ($1, $2, FALSE)\n " - }, - "ce20a9c53249e255be7312819f505d935d3ab2ee3c21a6422e5b12155c159bd7": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "team_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "member_role", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "permissions", - "ordinal": 3, - "type_info": "Int8" - }, - { - "name": "organization_permissions", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "accepted", - "ordinal": 5, - "type_info": "Bool" - }, - { - "name": "payouts_split", - "ordinal": 6, - "type_info": "Numeric" - }, - { - "name": "role", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "ordering", - "ordinal": 8, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 9, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false, - true, - false, - false, - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT id, team_id, role AS member_role, permissions, organization_permissions,\n accepted, payouts_split, role,\n ordering, user_id\n \n FROM team_members\n WHERE (team_id = $1 AND user_id = $2)\n ORDER BY ordering\n " - }, - "ce2e7642142f79bdce78ba3316fe402e18ae203cc65fe79f724d37a7076df2dd": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE collections\n SET title = $1\n WHERE (id = $2)\n " - }, - "cef01012769dcd499a0d16ce65ffc1e94bce362a7246b6a0a38d133afb90d3b6": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE team_members\n SET role = $1\n WHERE (team_id = $2 AND user_id = $3)\n " - }, - "cfcc6970c0b469c4afd37bedfd386def7980f6b7006030d4783723861d0e3a38": { - "describe": { - "columns": [ - { - "name": "version_id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "project_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "hash", - "ordinal": 2, - "type_info": "Bytea" - } - ], - "nullable": [ - false, - false, - false - ], - "parameters": { - "Left": [ - "ByteaArray" - ] - } - }, - "query": "\n SELECT v.id version_id, v.mod_id project_id, h.hash hash FROM hashes h\n INNER JOIN files f on h.file_id = f.id\n INNER JOIN versions v on f.version_id = v.id\n WHERE h.algorithm = 'sha1' AND h.hash = ANY($1)\n " - }, - "cfd80c4417c0534d24d65c782753927ba446e6ba542095c211ae5ee9b06b2753": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET gitlab_id = $2\n WHERE (id = $1)\n " - }, - "d1566672369ea22cb1f638f073f8e3fb467b354351ae71c67941323749ec9bcd": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Bytea", - "Text" - ] - } - }, - "query": "\n SELECT f.id id FROM hashes h\n INNER JOIN files f ON h.file_id = f.id\n WHERE h.algorithm = $2 AND h.hash = $1\n " - }, - "d203b99bd23d16224348e4fae44296aa0e1ea6d6a3fac26908303069b36a8dd0": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM threads_messages\n WHERE thread_id = $1\n " - }, - "d2c046d4bedeb7181ece4e94d7de90c97bd3dd1b0c16070704028923a0c2834a": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Jsonb" - ] - } - }, - "query": "\n INSERT INTO notifications (\n id, user_id, body\n )\n VALUES (\n $1, $2, $3\n )\n " - }, - "d331ca8f22da418cf654985c822ce4466824beaa00dea64cde90dc651a03024b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET moderation_message = $1\n WHERE (id = $2)\n " - }, - "d3991923355b2e0ed7bbe6c85d9158754d7e7d28f5ac75ee5b4e782dbc5c38a9": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE team_members\n SET accepted = TRUE\n WHERE (team_id = $1 AND user_id = $2)\n " - }, - "d3d1467a5dcfc3eb34d7e821b0de54a419d9a5391c13254478944f2f2cc78fe6": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Varchar", - "Int8", - "Int8", - "Timestamptz" - ] - } - }, - "query": "\n INSERT INTO pats (\n id, name, access_token, scopes, user_id,\n expires\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6\n )\n " - }, - "d3f317f7d767f5188bace4064d548d3049df0d06420e3a23ebd8f326703a448e": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET discord_id = $2\n WHERE (id = $1)\n " - }, - "d55bdef50adf0b8a547022d0a041bec8618da02d82a1138da77d8885c0d9cfb9": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "team_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "member_role", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "permissions", - "ordinal": 3, - "type_info": "Int8" - }, - { - "name": "organization_permissions", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "accepted", - "ordinal": 5, - "type_info": "Bool" - }, - { - "name": "payouts_split", - "ordinal": 6, - "type_info": "Numeric" - }, - { - "name": "role", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "ordering", - "ordinal": 8, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 9, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false, - true, - false, - false, - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8Array", - "Int8" - ] - } - }, - "query": "\n SELECT id, team_id, role AS member_role, permissions, organization_permissions,\n accepted, payouts_split, role,\n ordering, user_id\n FROM team_members\n WHERE (team_id = ANY($1) AND user_id = $2 AND accepted = TRUE)\n ORDER BY ordering\n " - }, - "d59a0ca4725d40232eae8bf5735787e1b76282c390d2a8d07fb34e237a0b2132": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4" - ] - } - }, - "query": "\n INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional)\n VALUES ($1, $2, TRUE)\n " - }, - "d6453e50041b5521fa9e919a9162e533bb9426f8c584d98474c6ad414db715c8": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM mods WHERE id=$1)" - }, - "d698ca87442da9d26bd1f4636af9a58509c2687f7621765663bdf18988c9c79e": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM organizations WHERE id=$1)" - }, - "d75b73151ba84715c06bbada22b66c819de8eac87c088b0a501212ad3fe4d618": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Bool", - "Int8" - ] - } - }, - "query": "\n UPDATE reports\n SET closed = $1\n WHERE (id = $2)\n " - }, - "d7c65c30898110d801a5bdf092564e5726e35c1033c69dba69008989a087357c": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Numeric", - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE team_members\n SET payouts_split = $1\n WHERE (team_id = $2 AND user_id = $3)\n " - }, - "d8020ed838c032c2c287dc0f08989b3ab7156f2571bc75505e6f57b0caeef9c7": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int4" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT id FROM donation_platforms\n WHERE short = $1\n " - }, - "d8b4e7e382c77a05395124d5a6a27cccb687d0e2c31b76d49b03aa364d099d42": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM files\n WHERE files.version_id = $1\n " - }, - "d93a8727fa8c7af79529670bdeab27100a2cdeeb605c85d0f30fd4962e731157": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM team_members\n WHERE team_id = $1\n " - }, - "d93ce03a186c03668d5eebab2bb4cbc4fc9dd002529e37575d94509b67908c8d": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "session", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "user_id", - "ordinal": 2, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT id, session, user_id\n FROM sessions\n WHERE refresh_expires <= NOW()\n " - }, - "dc6aa2e7bfd5d5004620ddd4cd6a47ecc56159e1489054e0652d56df802fb5e5": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET body = $1\n WHERE (id = $2)\n " - }, - "dcc32d760692674180471e7b19a9a1f73e77bb170e92cc7d60da37596ef840b0": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM threads\n WHERE id = $1\n " - }, - "dccd2b918e3bc37aa10ff0dd475d804110d267f959a7b4f854b302e9ceba2e70": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE dependencies\n SET dependency_id = NULL, mod_dependency_id = $2\n WHERE dependency_id = $1\n " - }, - "dd57a6dd89fefedbde796ef02b308ce7dba17ca0c65ffd5f9e35e296a72d4c1c": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "mod_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "file_type", - "ordinal": 2, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - true - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT v.id id, v.mod_id mod_id, file_type FROM files f\n INNER JOIN versions v ON v.id = f.version_id\n WHERE f.url = $1\n " - }, - "de1bf7e33a99a10154cefdbe3b8322e4c6a19448b6ee3c6087b1b8163bc52cb1": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n DELETE FROM user_backup_codes\n WHERE user_id = $1 AND code = $2\n " - }, - "debb47a2718f79684c8776da7f289b8d178c302bb5a69562b963b8d008973b8d": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE threads_messages\n SET body = '{\"type\": \"deleted\"}', author_id = $2\n WHERE author_id = $1\n " - }, - "df871bd959ba97f105ac575f34d8d2a39cbc44a07e0339750a0e477e6fd582ed": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8", - "Int8", - "Varchar", - "Varchar", - "Varchar", - "Timestamptz", - "Int4", - "Varchar", - "Bool", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO versions (\n id, mod_id, author_id, name, version_number,\n changelog, date_published, downloads,\n version_type, featured, status\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7, $8,\n $9, $10, $11\n )\n " - }, - "e3235e872f98eb85d3eb4a2518fb9dc88049ce62362bfd02623e9b49ac2e9fed": { - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Varchar" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT name FROM report_types\n " - }, - "e3389d233c75649e95456d504d1b716d520a03a8a3e0cc5311a4a753f1f04614": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM organizations WHERE title = LOWER($1))\n " - }, - "e37ecb6dc1509d390bb6f68ba25899d19f693554d8969bbf8f8ee14a78adf0f9": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Bool", - "Int8" - ] - } - }, - "query": "\n UPDATE threads\n SET show_in_mod_inbox = $1\n WHERE id = $2\n " - }, - "e3cc1fd070b97c4cc36bdb2f33080d4e0d7f3c3d81312d9d28a8c3c8213ad54b": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM files\n WHERE files.id = $1\n " - }, - "e3fb74a94a6a78b1007dd99ad11bdcfaa0957ed7d1683997aef7301e0f15baba": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET issues_url = $1\n WHERE (id = $2)\n " - }, - "e48c85a2b2e11691afae3799aa126bdd8b7338a973308bbab2760c18bb9cb0b7": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Bool", - "Int8" - ] - } - }, - "query": "\n UPDATE versions\n SET featured = $1\n WHERE (id = $2)\n " - }, - "e5adaf219c52ec828b72bd89c6b86a475f73181abf180a024dfe05f918e58edb": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "amount", - "ordinal": 1, - "type_info": "Numeric" - }, - { - "name": "user_id", - "ordinal": 2, - "type_info": "Int8" - }, - { - "name": "status", - "ordinal": 3, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - false, - false - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "SELECT id, amount, user_id, status FROM historical_payouts WHERE payment_id = $1" - }, - "e60ea75112db37d3e73812e21b1907716e4762e06aa883af878e3be82e3f87d3": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT c.id FROM collections c\n WHERE c.user_id = $1\n " - }, - "e6db02891be261e61a25716b83c1298482eb9a04f0c026532030aeb374405f13": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "team_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "member_role", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "permissions", - "ordinal": 3, - "type_info": "Int8" - }, - { - "name": "organization_permissions", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "accepted", - "ordinal": 5, - "type_info": "Bool" - }, - { - "name": "payouts_split", - "ordinal": 6, - "type_info": "Numeric" - }, - { - "name": "ordering", - "ordinal": 7, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 8, - "type_info": "Int8" - } - ], - "nullable": [ - false, - false, - false, - false, - true, - false, - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT id, team_id, role AS member_role, permissions, organization_permissions,\n accepted, payouts_split, \n ordering, user_id\n FROM team_members\n WHERE team_id = ANY($1)\n ORDER BY team_id, ordering;\n " - }, - "e6f5a150cbd3bd6b9bde9e5cdad224a45c96d678b69ec12508e81246710e3f6d": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "name", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "access_token", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "scopes", - "ordinal": 3, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 4, - "type_info": "Int8" - }, - { - "name": "created", - "ordinal": 5, - "type_info": "Timestamptz" - }, - { - "name": "expires", - "ordinal": 6, - "type_info": "Timestamptz" - }, - { - "name": "last_used", - "ordinal": 7, - "type_info": "Timestamptz" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - true - ], - "parameters": { - "Left": [ - "Int8Array", - "TextArray" - ] - } - }, - "query": "\n SELECT id, name, access_token, scopes, user_id, created, expires, last_used\n FROM pats\n WHERE id = ANY($1) OR access_token = ANY($2)\n ORDER BY created DESC\n " - }, - "e74fad4e44759b82df6cde8a4e6df7dc0eb31968a7acfb5069d9e5202c1ad803": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Text", - "Int8" - ] - } - }, - "query": "\n UPDATE organizations\n SET description = $1\n WHERE (id = $2)\n " - }, - "e7d0a64a08df6783c942f2fcadd94dd45f8d96ad3d3736e52ce90f68d396cdab": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM team_members WHERE id=$1)" - }, - "e8d4589132b094df1e7a3ca0440344fc8013c0d20b3c71a1142ccbee91fb3c70": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM teams WHERE id=$1)" - }, - "e925b15ec46f0263c7775ba1ba00ed11cfd6749fa792d4eabed73b619f230585": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET status = $1\n WHERE (id = $2)\n " - }, - "e9d863c1793939d5ae7137d810f23d06460c28a9058b251448e3786c436f80cd": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [] - } - }, - "query": "\n SELECT id\n FROM threads\n WHERE show_in_mod_inbox = TRUE\n " - }, - "ea1525cbe7460d0d9e9da8f448c661f7209bc1a7a04e2ea0026fa69c3f550a14": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT tm.user_id id\n FROM team_members tm\n WHERE tm.team_id = $1 AND tm.accepted\n " - }, - "ed1d5d9433bc7f4a360431ecfdd9430c5e58cd6d1c623c187d8661200400b1a4": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET moderation_message_body = $1\n WHERE (id = $2)\n " - }, - "ed3e866634135d4f4c8a513eae2856ad71212f6eec09bb4ccef1506912a3a44c": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n UPDATE mods\n SET follows = follows + 1\n WHERE id = $1\n " - }, - "ed47f363296ef7f8b3a8bedfd8108ca692811be1b9dce4a89ad151a6932e44c5": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT id\n FROM sessions\n WHERE user_id = $1\n ORDER BY created DESC\n " - }, - "ee2bca5618c3974147a4541bac1b2d8ca2c4a930769c11e10f6a97e3cac6ee2e": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT id FROM users WHERE discord_id = $1" - }, - "eec6d4028d790e57a4d97fc5a200a9ae2b3d2cb60ee83c51fb05180b821558f5": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE pats\n SET scopes = $1\n WHERE id = $2\n " - }, - "ef59f99fc0ab66ff5779d0e71c4a2134e2f26eed002ff9ea5626ea3e23518594": { - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Varchar" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT name FROM project_types pt\n INNER JOIN mods ON mods.project_type = pt.id\n WHERE mods.id = $1\n " - }, - "f141cc6711123b4fe5a5d9a7337a0b009b80e5d8fbda664b8d62b1a3f38eb936": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Numeric", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET balance = balance + $1\n WHERE id = $2\n " - }, - "f1525930830e17b5ee8feb796d9950dd3741131965f050840fa75423b5a54f01": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Varchar", - "Int8", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar", - "Varchar" - ] - } - }, - "query": "\n INSERT INTO sessions (\n id, session, user_id, os, platform,\n city, country, ip, user_agent\n )\n VALUES (\n $1, $2, $3, $4, $5,\n $6, $7, $8, $9\n )\n " - }, - "f17a109913015a7a5ab847bb2e73794d6261a08d450de24b450222755e520881": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n SELECT id FROM reports\n WHERE closed = FALSE AND reporter = $1\n ORDER BY created ASC\n LIMIT $2;\n " - }, - "f2c5eccd8099d6f527c1665cfc0f1204b8a0dab6f2b84f9f72fbf5462c6cb1f4": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE uploaded_images\n SET mod_id = $1\n WHERE id = $2\n " - }, - "f34bbe639ad21801258dc8beaab9877229a451761be07f85a1dd04d027832329": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM mods WHERE id=$1)\n " - }, - "f3d7eb1b62f0b978787dba1132308d070d28911d6ddc380cedfa16e7baa3243a": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "version_number", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "version_type", - "ordinal": 2, - "type_info": "Varchar" - } - ], - "nullable": [ - false, - false, - false - ], - "parameters": { - "Left": [ - "Int8", - "TextArray" - ] - } - }, - "query": "\n SELECT id, version_number, version_type\n FROM versions\n WHERE mod_id = $1 AND status = ANY($2)\n ORDER BY date_published ASC\n " - }, - "f453b43772c4d2d9d09dc389eb95482cc75e7f0eaf9dc7ff48cf40f22f1497cc": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Varchar", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET bio = $1\n WHERE (id = $2)\n " - }, - "f793e96499ff35f8dc2e420484c2a0cdb54f25ffa27caa081691779ab896a709": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM mods\n WHERE id = $1\n " - }, - "f85fc13148aafc03a4df68eaa389945e9dc6472a759525a48cfb23d31181535c": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM threads_messages WHERE id=$1)" - }, - "f88215069dbadf906c68c554b563021a34a935ce45d221cdf955f6a2c197d8b9": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n DELETE FROM organizations\n WHERE id = $1\n " - }, - "f8be3053274b00ee9743e798886696062009c5f681baaf29dfc24cfbbda93742": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Text" - ] - } - }, - "query": "\n SELECT EXISTS(SELECT 1 FROM mods WHERE slug = LOWER($1))\n " - }, - "f9bc19beaa70db45b058e80ba86599d393fad4c7d4af98426a8a9d9ca9b24035": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "\n UPDATE users\n SET steam_id = $2\n WHERE (id = $1)\n " - }, - "fa1b92b15cc108fa046998f789c8b259e0226e7dac16c635927ca74abc78cea9": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8", - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM mods m INNER JOIN team_members tm ON tm.team_id = m.team_id AND user_id = $2 WHERE m.id = $1)" - }, - "faec0a606ccaeb3f21c81e60a1749640b929e97db40252118fb72610df64a457": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "name", - "ordinal": 1, - "type_info": "Varchar" - }, - { - "name": "email", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "avatar_url", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "username", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "bio", - "ordinal": 5, - "type_info": "Varchar" - }, - { - "name": "created", - "ordinal": 6, - "type_info": "Timestamptz" - }, - { - "name": "role", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "badges", - "ordinal": 8, - "type_info": "Int8" - }, - { - "name": "balance", - "ordinal": 9, - "type_info": "Numeric" - }, - { - "name": "github_id", - "ordinal": 10, - "type_info": "Int8" - }, - { - "name": "discord_id", - "ordinal": 11, - "type_info": "Int8" - }, - { - "name": "gitlab_id", - "ordinal": 12, - "type_info": "Int8" - }, - { - "name": "google_id", - "ordinal": 13, - "type_info": "Varchar" - }, - { - "name": "steam_id", - "ordinal": 14, - "type_info": "Int8" - }, - { - "name": "microsoft_id", - "ordinal": 15, - "type_info": "Varchar" - }, - { - "name": "email_verified", - "ordinal": 16, - "type_info": "Bool" - }, - { - "name": "password", - "ordinal": 17, - "type_info": "Text" - }, - { - "name": "totp_secret", - "ordinal": 18, - "type_info": "Varchar" - }, - { - "name": "trolley_id", - "ordinal": 19, - "type_info": "Text" - }, - { - "name": "trolley_account_status", - "ordinal": 20, - "type_info": "Text" - } - ], - "nullable": [ - false, - true, - true, - true, - false, - true, - false, - false, - false, - false, - true, - true, - true, - true, - true, - true, - false, - true, - true, - true, - true - ], - "parameters": { - "Left": [ - "Int8Array", - "TextArray" - ] - } - }, - "query": "\n SELECT id, name, email,\n avatar_url, username, bio,\n created, role, badges,\n balance,\n github_id, discord_id, gitlab_id, google_id, steam_id, microsoft_id,\n email_verified, password, totp_secret, trolley_id, trolley_account_status\n FROM users\n WHERE id = ANY($1) OR LOWER(username) = ANY($2)\n " - }, - "fb955ca41b95120f66c98c0b528b1db10c4be4a55e9641bb104d772e390c9bb7": { - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Bool" - } - ], - "nullable": [ - null - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "SELECT EXISTS(SELECT 1 FROM notifications WHERE id=$1)" - }, - "fcd15905507769ab7f9839d64d1be3ee3f61cd555aee57dace76f8e53e91d344": { - "describe": { - "columns": [], - "nullable": [], - "parameters": { - "Left": [ - "Int8", - "Int4" - ] - } - }, - "query": "\n INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional)\n VALUES ($1, $2, TRUE)\n " - }, - "fce67ce3d0c27c64af85fb7d36661513bc5ea2e96fcf12f3a51c97999b01b83c": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "user_id", - "ordinal": 1, - "type_info": "Int8" - }, - { - "name": "title", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "text", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "link", - "ordinal": 4, - "type_info": "Varchar" - }, - { - "name": "created", - "ordinal": 5, - "type_info": "Timestamptz" - }, - { - "name": "read", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "notification_type", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "body", - "ordinal": 8, - "type_info": "Jsonb" - }, - { - "name": "actions", - "ordinal": 9, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - true, - true, - true, - false, - false, - true, - true, - null - ], - "parameters": { - "Left": [ - "Int8Array" - ] - } - }, - "query": "\n SELECT n.id, n.user_id, n.title, n.text, n.link, n.created, n.read, n.type notification_type, n.body,\n JSONB_AGG(DISTINCT jsonb_build_object('id', na.id, 'notification_id', na.notification_id, 'title', na.title, 'action_route_method', na.action_route_method, 'action_route', na.action_route)) filter (where na.id is not null) actions\n FROM notifications n\n LEFT OUTER JOIN notifications_actions na on n.id = na.notification_id\n WHERE n.id = ANY($1)\n GROUP BY n.id, n.user_id\n ORDER BY n.created DESC;\n " - }, - "fdfe36dcb85347a3a8228b5d5fc2d017b9baa307b5ae0ae9deaafab9dcdcb74a": { - "describe": { - "columns": [ - { - "name": "follower_id", - "ordinal": 0, - "type_info": "Int8" - } - ], - "nullable": [ - false - ], - "parameters": { - "Left": [ - "Int8" - ] - } - }, - "query": "\n SELECT follower_id FROM mod_follows\n WHERE mod_id = $1\n " - }, - "ffcc8c65721465514ad39a0e9bd6138eda0fa32dd3399a8e850a76beb1f1bf16": { - "describe": { - "columns": [ - { - "name": "id", - "ordinal": 0, - "type_info": "Int8" - }, - { - "name": "project_type", - "ordinal": 1, - "type_info": "Int4" - }, - { - "name": "title", - "ordinal": 2, - "type_info": "Varchar" - }, - { - "name": "description", - "ordinal": 3, - "type_info": "Varchar" - }, - { - "name": "downloads", - "ordinal": 4, - "type_info": "Int4" - }, - { - "name": "follows", - "ordinal": 5, - "type_info": "Int4" - }, - { - "name": "icon_url", - "ordinal": 6, - "type_info": "Varchar" - }, - { - "name": "body", - "ordinal": 7, - "type_info": "Varchar" - }, - { - "name": "published", - "ordinal": 8, - "type_info": "Timestamptz" - }, - { - "name": "updated", - "ordinal": 9, - "type_info": "Timestamptz" - }, - { - "name": "approved", - "ordinal": 10, - "type_info": "Timestamptz" - }, - { - "name": "queued", - "ordinal": 11, - "type_info": "Timestamptz" - }, - { - "name": "status", - "ordinal": 12, - "type_info": "Varchar" - }, - { - "name": "requested_status", - "ordinal": 13, - "type_info": "Varchar" - }, - { - "name": "issues_url", - "ordinal": 14, - "type_info": "Varchar" - }, - { - "name": "source_url", - "ordinal": 15, - "type_info": "Varchar" - }, - { - "name": "wiki_url", - "ordinal": 16, - "type_info": "Varchar" - }, - { - "name": "discord_url", - "ordinal": 17, - "type_info": "Varchar" - }, - { - "name": "license_url", - "ordinal": 18, - "type_info": "Varchar" - }, - { - "name": "team_id", - "ordinal": 19, - "type_info": "Int8" - }, - { - "name": "organization_id", - "ordinal": 20, - "type_info": "Int8" - }, - { - "name": "client_side", - "ordinal": 21, - "type_info": "Int4" - }, - { - "name": "server_side", - "ordinal": 22, - "type_info": "Int4" - }, - { - "name": "license", - "ordinal": 23, - "type_info": "Varchar" - }, - { - "name": "slug", - "ordinal": 24, - "type_info": "Varchar" - }, - { - "name": "moderation_message", - "ordinal": 25, - "type_info": "Varchar" - }, - { - "name": "moderation_message_body", - "ordinal": 26, - "type_info": "Varchar" - }, - { - "name": "client_side_type", - "ordinal": 27, - "type_info": "Varchar" - }, - { - "name": "server_side_type", - "ordinal": 28, - "type_info": "Varchar" - }, - { - "name": "project_type_name", - "ordinal": 29, - "type_info": "Varchar" - }, - { - "name": "webhook_sent", - "ordinal": 30, - "type_info": "Bool" - }, - { - "name": "color", - "ordinal": 31, - "type_info": "Int4" - }, - { - "name": "thread_id", - "ordinal": 32, - "type_info": "Int8" - }, - { - "name": "monetization_status", - "ordinal": 33, - "type_info": "Varchar" - }, - { - "name": "loaders", - "ordinal": 34, - "type_info": "VarcharArray" - }, - { - "name": "game_versions", - "ordinal": 35, - "type_info": "VarcharArray" - }, - { - "name": "categories", - "ordinal": 36, - "type_info": "VarcharArray" - }, - { - "name": "additional_categories", - "ordinal": 37, - "type_info": "VarcharArray" - }, - { - "name": "versions", - "ordinal": 38, - "type_info": "Jsonb" - }, - { - "name": "gallery", - "ordinal": 39, - "type_info": "Jsonb" - }, - { - "name": "donations", - "ordinal": 40, - "type_info": "Jsonb" - } - ], - "nullable": [ - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - true, - true, - false, - true, - true, - true, - true, - true, - true, - false, - true, - false, - false, - false, - true, - true, - true, - false, - false, - false, - false, - true, - false, - false, - false, - false, - null, - null, - null, - null, - null - ], - "parameters": { - "Left": [ - "Int8Array", - "TextArray", - "TextArray" - ] - } - }, - "query": "\n SELECT m.id id, m.project_type project_type, m.title title, m.description description, m.downloads downloads, m.follows follows,\n m.icon_url icon_url, m.body body, m.published published,\n m.updated updated, m.approved approved, m.queued, m.status status, m.requested_status requested_status,\n m.issues_url issues_url, m.source_url source_url, m.wiki_url wiki_url, m.discord_url discord_url, m.license_url license_url,\n m.team_id team_id, m.organization_id organization_id, m.client_side client_side, m.server_side server_side, m.license license, m.slug slug, m.moderation_message moderation_message, m.moderation_message_body moderation_message_body,\n cs.name client_side_type, ss.name server_side_type, pt.name project_type_name, m.webhook_sent, m.color,\n t.id thread_id, m.monetization_status monetization_status, m.loaders loaders, m.game_versions game_versions,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is false) categories,\n ARRAY_AGG(DISTINCT c.category) filter (where c.category is not null and mc.is_additional is true) additional_categories,\n JSONB_AGG(DISTINCT jsonb_build_object('id', v.id, 'date_published', v.date_published)) filter (where v.id is not null) versions,\n JSONB_AGG(DISTINCT jsonb_build_object('image_url', mg.image_url, 'featured', mg.featured, 'title', mg.title, 'description', mg.description, 'created', mg.created, 'ordering', mg.ordering)) filter (where mg.image_url is not null) gallery,\n JSONB_AGG(DISTINCT jsonb_build_object('platform_id', md.joining_platform_id, 'platform_short', dp.short, 'platform_name', dp.name,'url', md.url)) filter (where md.joining_platform_id is not null) donations\n FROM mods m\n INNER JOIN project_types pt ON pt.id = m.project_type\n INNER JOIN side_types cs ON m.client_side = cs.id\n INNER JOIN side_types ss ON m.server_side = ss.id\n INNER JOIN threads t ON t.mod_id = m.id\n LEFT JOIN mods_gallery mg ON mg.mod_id = m.id\n LEFT JOIN mods_donations md ON md.joining_mod_id = m.id\n LEFT JOIN donation_platforms dp ON md.joining_platform_id = dp.id\n LEFT JOIN mods_categories mc ON mc.joining_mod_id = m.id\n LEFT JOIN categories c ON mc.joining_category_id = c.id\n LEFT JOIN versions v ON v.mod_id = m.id AND v.status = ANY($3)\n WHERE m.id = ANY($1) OR m.slug = ANY($2)\n GROUP BY pt.id, cs.id, ss.id, t.id, m.id;\n " - } -} \ No newline at end of file diff --git a/src/clickhouse/mod.rs b/src/clickhouse/mod.rs index 09722462..c46c0089 100644 --- a/src/clickhouse/mod.rs +++ b/src/clickhouse/mod.rs @@ -6,8 +6,12 @@ mod fetch; pub use fetch::*; pub async fn init_client() -> clickhouse::error::Result { - let database = dotenvy::var("CLICKHOUSE_DATABASE").unwrap(); + init_client_with_database(&dotenvy::var("CLICKHOUSE_DATABASE").unwrap()).await +} +pub async fn init_client_with_database( + database: &str, +) -> clickhouse::error::Result { let client = { let mut http_connector = HttpConnector::new(); http_connector.enforce_http(false); // allow https URLs diff --git a/src/database/models/collection_item.rs b/src/database/models/collection_item.rs index 8e1c1cae..d0cf23e7 100644 --- a/src/database/models/collection_item.rs +++ b/src/database/models/collection_item.rs @@ -81,19 +81,19 @@ impl Collection { .execute(&mut *transaction) .await?; - for project_id in self.projects.iter() { - sqlx::query!( - " - INSERT INTO collections_mods (collection_id, mod_id) - VALUES ($1, $2) - ON CONFLICT DO NOTHING - ", - self.id as CollectionId, - *project_id as ProjectId, - ) - .execute(&mut *transaction) - .await?; - } + let (collection_ids, project_ids): (Vec<_>, Vec<_>) = + self.projects.iter().map(|p| (self.id.0, p.0)).unzip(); + sqlx::query!( + " + INSERT INTO collections_mods (collection_id, mod_id) + SELECT * FROM UNNEST($1::bigint[], $2::bigint[]) + ON CONFLICT DO NOTHING + ", + &collection_ids[..], + &project_ids[..], + ) + .execute(&mut *transaction) + .await?; Ok(()) } diff --git a/src/database/models/project_item.rs b/src/database/models/project_item.rs index 65605ab7..68e44967 100644 --- a/src/database/models/project_item.rs +++ b/src/database/models/project_item.rs @@ -5,6 +5,7 @@ use crate::database::redis::RedisPool; use crate::models::ids::base62_impl::{parse_base62, to_base62}; use crate::models::projects::{MonetizationStatus, ProjectStatus}; use chrono::{DateTime, Utc}; +use itertools::Itertools; use serde::{Deserialize, Serialize}; pub const PROJECTS_NAMESPACE: &str = "projects"; @@ -20,23 +21,25 @@ pub struct DonationUrl { } impl DonationUrl { - pub async fn insert_project( - &self, + pub async fn insert_many_projects( + donation_urls: Vec, project_id: ProjectId, transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result<(), sqlx::error::Error> { + let (project_ids, platform_ids, urls): (Vec<_>, Vec<_>, Vec<_>) = donation_urls + .into_iter() + .map(|url| (project_id.0, url.platform_id.0, url.url)) + .multiunzip(); sqlx::query!( " INSERT INTO mods_donations ( joining_mod_id, joining_platform_id, url ) - VALUES ( - $1, $2, $3 - ) + SELECT * FROM UNNEST($1::bigint[], $2::int[], $3::varchar[]) ", - project_id as ProjectId, - self.platform_id as DonationPlatformId, - self.url, + &project_ids[..], + &platform_ids[..], + &urls[..], ) .execute(&mut *transaction) .await?; @@ -56,26 +59,76 @@ pub struct GalleryItem { } impl GalleryItem { - pub async fn insert( - &self, + pub async fn insert_many( + items: Vec, project_id: ProjectId, transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result<(), sqlx::error::Error> { + let (project_ids, image_urls, featureds, titles, descriptions, orderings): ( + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + ) = items + .into_iter() + .map(|gi| { + ( + project_id.0, + gi.image_url, + gi.featured, + gi.title, + gi.description, + gi.ordering, + ) + }) + .multiunzip(); sqlx::query!( " INSERT INTO mods_gallery ( mod_id, image_url, featured, title, description, ordering ) - VALUES ( - $1, $2, $3, $4, $5, $6 - ) + SELECT * FROM UNNEST ($1::bigint[], $2::varchar[], $3::bool[], $4::varchar[], $5::varchar[], $6::bigint[]) ", - project_id as ProjectId, - self.image_url, - self.featured, - self.title, - self.description, - self.ordering + &project_ids[..], + &image_urls[..], + &featureds[..], + &titles[..] as &[Option], + &descriptions[..] as &[Option], + &orderings[..] + ) + .execute(&mut *transaction) + .await?; + + Ok(()) + } +} + +#[derive(derive_new::new)] +pub struct ModCategory { + project_id: ProjectId, + category_id: CategoryId, + is_additional: bool, +} + +impl ModCategory { + pub async fn insert_many( + items: Vec, + transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + ) -> Result<(), DatabaseError> { + let (project_ids, category_ids, is_additionals): (Vec<_>, Vec<_>, Vec<_>) = items + .into_iter() + .map(|mc| (mc.project_id.0, mc.category_id.0, mc.is_additional)) + .multiunzip(); + sqlx::query!( + " + INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional) + SELECT * FROM UNNEST ($1::bigint[], $2::int[], $3::bool[]) + ", + &project_ids[..], + &category_ids[..], + &is_additionals[..] ) .execute(&mut *transaction) .await?; @@ -160,46 +213,35 @@ impl ProjectBuilder { }; project_struct.insert(&mut *transaction).await?; + let ProjectBuilder { + donation_urls, + gallery_items, + categories, + additional_categories, + .. + } = self; + for mut version in self.initial_versions { version.project_id = self.project_id; version.insert(&mut *transaction).await?; } - for donation in self.donation_urls { - donation - .insert_project(self.project_id, &mut *transaction) - .await?; - } - - for gallery in self.gallery_items { - gallery.insert(self.project_id, &mut *transaction).await?; - } - - for category in self.categories { - sqlx::query!( - " - INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional) - VALUES ($1, $2, FALSE) - ", - self.project_id as ProjectId, - category as CategoryId, - ) - .execute(&mut *transaction) + DonationUrl::insert_many_projects(donation_urls, self.project_id, &mut *transaction) .await?; - } - for category in self.additional_categories { - sqlx::query!( - " - INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional) - VALUES ($1, $2, TRUE) - ", - self.project_id as ProjectId, - category as CategoryId, + GalleryItem::insert_many(gallery_items, self.project_id, &mut *transaction).await?; + + let project_id = self.project_id; + let mod_categories = categories + .into_iter() + .map(|c| ModCategory::new(project_id, c, false)) + .chain( + additional_categories + .into_iter() + .map(|c| ModCategory::new(project_id, c, true)), ) - .execute(&mut *transaction) - .await?; - } + .collect_vec(); + ModCategory::insert_many(mod_categories, &mut *transaction).await?; Project::update_game_versions(self.project_id, &mut *transaction).await?; Project::update_loaders(self.project_id, &mut *transaction).await?; diff --git a/src/database/models/team_item.rs b/src/database/models/team_item.rs index 31d60b20..a6e7c783 100644 --- a/src/database/models/team_item.rs +++ b/src/database/models/team_item.rs @@ -41,26 +41,61 @@ impl TeamBuilder { .execute(&mut *transaction) .await?; - for member in self.members { - let team_member_id = generate_team_member_id(&mut *transaction).await?; - sqlx::query!( - " - INSERT INTO team_members (id, team_id, user_id, role, permissions, organization_permissions, accepted, payouts_split, ordering) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) - ", - team_member_id as TeamMemberId, - team.id as TeamId, - member.user_id as UserId, - member.role, - member.permissions.bits() as i64, - member.organization_permissions.map(|p| p.bits() as i64), - member.accepted, - member.payouts_split, - member.ordering, - ) - .execute(&mut *transaction) - .await?; + let mut team_member_ids = Vec::new(); + for _ in self.members.iter() { + team_member_ids.push(generate_team_member_id(&mut *transaction).await?.0); } + let TeamBuilder { members } = self; + let ( + team_ids, + user_ids, + roles, + permissions, + organization_permissions, + accepteds, + payouts_splits, + orderings, + ): ( + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + ) = members + .into_iter() + .map(|m| { + ( + team.id.0, + m.user_id.0, + m.role, + m.permissions.bits() as i64, + m.organization_permissions.map(|p| p.bits() as i64), + m.accepted, + m.payouts_split, + m.ordering, + ) + }) + .multiunzip(); + sqlx::query!( + " + INSERT INTO team_members (id, team_id, user_id, role, permissions, organization_permissions, accepted, payouts_split, ordering) + SELECT * FROM UNNEST ($1::int8[], $2::int8[], $3::int8[], $4::varchar[], $5::int8[], $6::int8[], $7::bool[], $8::numeric[], $9::int8[]) + ", + &team_member_ids[..], + &team_ids[..], + &user_ids[..], + &roles[..], + &permissions[..], + &organization_permissions[..] as &[Option], + &accepteds[..], + &payouts_splits[..], + &orderings[..], + ) + .execute(&mut *transaction) + .await?; Ok(team_id) } diff --git a/src/database/models/thread_item.rs b/src/database/models/thread_item.rs index eea137cb..afad3241 100644 --- a/src/database/models/thread_item.rs +++ b/src/database/models/thread_item.rs @@ -90,22 +90,20 @@ impl ThreadBuilder { .execute(&mut *transaction) .await?; - for member in &self.members { - sqlx::query!( - " - INSERT INTO threads_members ( - thread_id, user_id - ) - VALUES ( - $1, $2 - ) - ", - thread_id as ThreadId, - *member as UserId, + let (thread_ids, members): (Vec<_>, Vec<_>) = + self.members.iter().map(|m| (thread_id.0, m.0)).unzip(); + sqlx::query!( + " + INSERT INTO threads_members ( + thread_id, user_id ) - .execute(&mut *transaction) - .await?; - } + SELECT * FROM UNNEST ($1::int8[], $2::int8[]) + ", + &thread_ids[..], + &members[..], + ) + .execute(&mut *transaction) + .await?; Ok(thread_id) } diff --git a/src/database/models/version_item.rs b/src/database/models/version_item.rs index a4e1b9f7..49933677 100644 --- a/src/database/models/version_item.rs +++ b/src/database/models/version_item.rs @@ -39,12 +39,59 @@ pub struct DependencyBuilder { } impl DependencyBuilder { - pub async fn insert( - self, + pub async fn insert_many( + builders: Vec, version_id: VersionId, transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result<(), DatabaseError> { - let project_id = if let Some(project_id) = self.project_id { + let mut project_ids = Vec::new(); + for dependency in builders.iter() { + project_ids.push( + dependency + .try_get_project_id(transaction) + .await? + .map(|id| id.0), + ); + } + + let (version_ids, dependency_types, dependency_ids, filenames): ( + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + ) = builders + .into_iter() + .map(|d| { + ( + version_id.0, + d.dependency_type, + d.version_id.map(|v| v.0), + d.file_name, + ) + }) + .multiunzip(); + sqlx::query!( + " + INSERT INTO dependencies (dependent_id, dependency_type, dependency_id, mod_dependency_id, dependency_file_name) + SELECT * FROM UNNEST ($1::bigint[], $2::varchar[], $3::bigint[], $4::bigint[], $5::varchar[]) + ", + &version_ids[..], + &dependency_types[..], + &dependency_ids[..] as &[Option], + &project_ids[..] as &[Option], + &filenames[..] as &[Option], + ) + .execute(&mut *transaction) + .await?; + + Ok(()) + } + + async fn try_get_project_id( + &self, + transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + ) -> Result, DatabaseError> { + Ok(if let Some(project_id) = self.project_id { Some(project_id) } else if let Some(version_id) = self.version_id { sqlx::query!( @@ -58,23 +105,7 @@ impl DependencyBuilder { .map(|x| ProjectId(x.mod_id)) } else { None - }; - - sqlx::query!( - " - INSERT INTO dependencies (dependent_id, dependency_type, dependency_id, mod_dependency_id, dependency_file_name) - VALUES ($1, $2, $3, $4, $5) - ", - version_id as VersionId, - self.dependency_type, - self.version_id.map(|x| x.0), - project_id.map(|x| x.0), - self.file_name, - ) - .execute(&mut *transaction) - .await?; - - Ok(()) + }) } } @@ -89,42 +120,70 @@ pub struct VersionFileBuilder { } impl VersionFileBuilder { - pub async fn insert( - self, + pub async fn insert_many( + version_files: Vec, version_id: VersionId, transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, ) -> Result { let file_id = generate_file_id(&mut *transaction).await?; + let (file_ids, version_ids, urls, filenames, primary, sizes, file_types): ( + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + Vec<_>, + ) = version_files + .iter() + .map(|f| { + ( + file_id.0, + version_id.0, + f.url.clone(), + f.filename.clone(), + f.primary, + f.size as i32, + f.file_type.map(|x| x.to_string()), + ) + }) + .multiunzip(); sqlx::query!( " INSERT INTO files (id, version_id, url, filename, is_primary, size, file_type) - VALUES ($1, $2, $3, $4, $5, $6, $7) + SELECT * FROM UNNEST($1::bigint[], $2::bigint[], $3::varchar[], $4::varchar[], $5::bool[], $6::integer[], $7::varchar[]) ", - file_id as FileId, - version_id as VersionId, - self.url, - self.filename, - self.primary, - self.size as i32, - self.file_type.map(|x| x.as_str()), + &file_ids[..], + &version_ids[..], + &urls[..], + &filenames[..], + &primary[..], + &sizes[..], + &file_types[..] as &[Option], ) .execute(&mut *transaction) .await?; - for hash in self.hashes { - sqlx::query!( - " - INSERT INTO hashes (file_id, algorithm, hash) - VALUES ($1, $2, $3) - ", - file_id as FileId, - hash.algorithm, - hash.hash, - ) - .execute(&mut *transaction) - .await?; - } + let (file_ids, algorithms, hashes): (Vec<_>, Vec<_>, Vec<_>) = version_files + .into_iter() + .flat_map(|f| { + f.hashes + .into_iter() + .map(|h| (file_id.0, h.algorithm, h.hash)) + }) + .multiunzip(); + sqlx::query!( + " + INSERT INTO hashes (file_id, algorithm, hash) + SELECT * FROM UNNEST($1::bigint[], $2::varchar[], $3::bytea[]) + ", + &file_ids[..], + &algorithms[..], + &hashes[..], + ) + .execute(&mut *transaction) + .await?; Ok(file_id) } @@ -170,41 +229,91 @@ impl VersionBuilder { .execute(&mut *transaction) .await?; - for file in self.files { - file.insert(self.version_id, transaction).await?; - } + let VersionBuilder { + dependencies, + loaders, + game_versions, + files, + version_id, + .. + } = self; + VersionFileBuilder::insert_many(files, self.version_id, transaction).await?; + + DependencyBuilder::insert_many(dependencies, self.version_id, transaction).await?; + + let loader_versions = loaders + .iter() + .map(|l| LoaderVersion::new(*l, version_id)) + .collect_vec(); + LoaderVersion::insert_many(loader_versions, &mut *transaction).await?; + + let game_version_versions = game_versions + .iter() + .map(|v| VersionVersion::new(*v, version_id)) + .collect_vec(); + VersionVersion::insert_many(game_version_versions, &mut *transaction).await?; - for dependency in self.dependencies { - dependency.insert(self.version_id, transaction).await?; - } + Ok(self.version_id) + } +} - for loader in self.loaders.clone() { - sqlx::query!( - " - INSERT INTO loaders_versions (loader_id, version_id) - VALUES ($1, $2) - ", - loader as LoaderId, - self.version_id as VersionId, - ) - .execute(&mut *transaction) - .await?; - } +#[derive(derive_new::new)] +pub struct LoaderVersion { + pub loader_id: LoaderId, + pub version_id: VersionId, +} - for game_version in self.game_versions.clone() { - sqlx::query!( - " - INSERT INTO game_versions_versions (game_version_id, joining_version_id) - VALUES ($1, $2) - ", - game_version as GameVersionId, - self.version_id as VersionId, - ) - .execute(&mut *transaction) - .await?; - } +impl LoaderVersion { + pub async fn insert_many( + items: Vec, + transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + ) -> Result<(), DatabaseError> { + let (loader_ids, version_ids): (Vec<_>, Vec<_>) = items + .iter() + .map(|l| (l.loader_id.0, l.version_id.0)) + .unzip(); + sqlx::query!( + " + INSERT INTO loaders_versions (loader_id, version_id) + SELECT * FROM UNNEST($1::integer[], $2::bigint[]) + ", + &loader_ids[..], + &version_ids[..], + ) + .execute(&mut *transaction) + .await?; - Ok(self.version_id) + Ok(()) + } +} + +#[derive(derive_new::new)] +pub struct VersionVersion { + pub game_version_id: GameVersionId, + pub joining_version_id: VersionId, +} + +impl VersionVersion { + pub async fn insert_many( + items: Vec, + transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, + ) -> Result<(), DatabaseError> { + let (game_version_ids, version_ids): (Vec<_>, Vec<_>) = items + .into_iter() + .map(|i| (i.game_version_id.0, i.joining_version_id.0)) + .unzip(); + sqlx::query!( + " + INSERT INTO game_versions_versions (game_version_id, joining_version_id) + SELECT * FROM UNNEST($1::integer[], $2::bigint[]) + ", + &game_version_ids[..], + &version_ids[..], + ) + .execute(&mut *transaction) + .await?; + + Ok(()) } } diff --git a/src/queue/analytics.rs b/src/queue/analytics.rs index 93b6a65d..8a02d99c 100644 --- a/src/queue/analytics.rs +++ b/src/queue/analytics.rs @@ -1,6 +1,13 @@ use crate::models::analytics::{Download, PageView, Playtime}; use dashmap::DashSet; +#[cfg(test)] +mod tests; + +const VIEWS_TABLENAME: &str = "views"; +const DOWNLOADS_TABLENAME: &str = "downloads"; +const PLAYTIME_TABLENAME: &str = "playtime"; + pub struct AnalyticsQueue { views_queue: DashSet, downloads_queue: DashSet, @@ -23,54 +30,50 @@ impl AnalyticsQueue { } } - pub async fn add_view(&self, page_view: PageView) { + pub fn add_view(&self, page_view: PageView) { self.views_queue.insert(page_view); } - pub async fn add_download(&self, download: Download) { + pub fn add_download(&self, download: Download) { self.downloads_queue.insert(download); } - pub async fn add_playtime(&self, playtime: Playtime) { + pub fn add_playtime(&self, playtime: Playtime) { self.playtime_queue.insert(playtime); } pub async fn index(&self, client: clickhouse::Client) -> Result<(), clickhouse::error::Error> { - let views_queue = self.views_queue.clone(); - self.views_queue.clear(); - - let downloads_queue = self.downloads_queue.clone(); - self.downloads_queue.clear(); - - let playtime_queue = self.playtime_queue.clone(); - self.playtime_queue.clear(); - - if !views_queue.is_empty() || !downloads_queue.is_empty() || !playtime_queue.is_empty() { - let mut views = client.insert("views")?; - - for view in views_queue { - views.write(&view).await?; - } + Self::index_queue(&client, &self.views_queue, VIEWS_TABLENAME).await?; + Self::index_queue(&client, &self.downloads_queue, DOWNLOADS_TABLENAME).await?; + Self::index_queue(&client, &self.playtime_queue, PLAYTIME_TABLENAME).await?; - views.end().await?; - - let mut downloads = client.insert("downloads")?; - - for download in downloads_queue { - downloads.write(&download).await?; - } + Ok(()) + } - downloads.end().await?; + async fn index_queue( + client: &clickhouse::Client, + queue: &DashSet, + table_name: &str, + ) -> Result<(), clickhouse::error::Error> + where + T: serde::Serialize + Eq + std::hash::Hash + Clone + clickhouse::Row, + { + if queue.is_empty() { + return Ok(()); + } - let mut playtimes = client.insert("playtime")?; + let current_queue = queue.clone(); + queue.clear(); - for playtime in playtime_queue { - playtimes.write(&playtime).await?; - } + let mut inserter = client.inserter(table_name)?; - playtimes.end().await?; + for row in current_queue { + inserter.write(&row).await?; + inserter.commit().await?; } + inserter.end().await?; + Ok(()) } } diff --git a/src/queue/analytics/tests.rs b/src/queue/analytics/tests.rs new file mode 100644 index 00000000..52b3d8e1 --- /dev/null +++ b/src/queue/analytics/tests.rs @@ -0,0 +1,128 @@ +use futures::Future; +use uuid::Uuid; + +use super::*; +use crate::clickhouse::init_client_with_database; +use std::net::Ipv6Addr; + +#[tokio::test] +async fn test_indexing() { + with_test_clickhouse_db(|clickhouse_client| async move { + let analytics = AnalyticsQueue::new(); + + analytics.add_download(get_default_download()); + analytics.add_playtime(get_default_playtime()); + analytics.add_view(get_default_views()); + + analytics.index(clickhouse_client.clone()).await.unwrap(); + assert_table_counts(&clickhouse_client, 1, 1, 1).await; + + analytics.index(clickhouse_client.clone()).await.unwrap(); + assert_table_counts(&clickhouse_client, 1, 1, 1).await; + }) + .await; +} + +#[tokio::test] +async fn can_insert_many_downloads() { + with_test_clickhouse_db(|clickhouse_client| async move { + let analytics = AnalyticsQueue::new(); + let n_downloads = 100_000; + + for _ in 0..n_downloads { + analytics.add_download(get_default_download()); + } + + analytics.index(clickhouse_client.clone()).await.unwrap(); + assert_table_count(DOWNLOADS_TABLENAME, &clickhouse_client, n_downloads).await; + }) + .await; +} + +async fn assert_table_counts( + client: &clickhouse::Client, + downloads: u64, + playtimes: u64, + views: u64, +) { + assert_table_count(DOWNLOADS_TABLENAME, client, downloads).await; + assert_table_count(PLAYTIME_TABLENAME, client, playtimes).await; + assert_table_count(VIEWS_TABLENAME, client, views).await; +} + +async fn assert_table_count(table_name: &str, client: &clickhouse::Client, expected_count: u64) { + let count = client + .query(&format!("SELECT COUNT(*) from {table_name}")) + .fetch_one::() + .await + .unwrap(); + assert_eq!(expected_count, count); +} + +async fn with_test_clickhouse_db(f: impl FnOnce(clickhouse::Client) -> Fut) +where + Fut: Future, +{ + let db_name = format!("test_{}", uuid::Uuid::new_v4().as_simple()); + println!("Clickhouse test db: {}", db_name); + let clickhouse_client = init_client_with_database(&db_name) + .await + .expect("A real clickhouse instance should be running locally"); + + f(clickhouse_client.clone()).await; + + clickhouse_client + .query(&format!("DROP DATABASE IF EXISTS {db_name}")) + .execute() + .await + .unwrap(); +} + +fn get_default_download() -> Download { + Download { + id: Uuid::new_v4(), + recorded: Default::default(), + domain: Default::default(), + site_path: Default::default(), + user_id: Default::default(), + project_id: Default::default(), + version_id: Default::default(), + ip: get_default_ipv6(), + country: Default::default(), + user_agent: Default::default(), + headers: Default::default(), + } +} + +fn get_default_playtime() -> Playtime { + Playtime { + id: Uuid::new_v4(), + recorded: Default::default(), + seconds: Default::default(), + user_id: Default::default(), + project_id: Default::default(), + version_id: Default::default(), + loader: Default::default(), + game_version: Default::default(), + parent: Default::default(), + } +} + +fn get_default_views() -> PageView { + PageView { + id: Uuid::new_v4(), + recorded: Default::default(), + domain: Default::default(), + site_path: Default::default(), + user_id: Default::default(), + project_id: Default::default(), + ip: get_default_ipv6(), + country: Default::default(), + user_agent: Default::default(), + headers: Default::default(), + } +} + +fn get_default_ipv6() -> Ipv6Addr { + Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) +} diff --git a/src/queue/payouts.rs b/src/queue/payouts.rs index 0ff097a9..aaa0a9c3 100644 --- a/src/queue/payouts.rs +++ b/src/queue/payouts.rs @@ -484,6 +484,8 @@ pub async fn process_payout( }; let mut clear_cache_users = Vec::new(); + let (mut insert_user_ids, mut insert_project_ids, mut insert_payouts, mut insert_starts) = + (Vec::new(), Vec::new(), Vec::new(), Vec::new()); for (id, project) in projects_map { if let Some(value) = &multipliers.values.get(&(id as u64)) { let project_multiplier: Decimal = @@ -496,18 +498,10 @@ pub async fn process_payout( let payout: Decimal = payout * project_multiplier * (split / sum_splits); if payout > Decimal::ZERO { - sqlx::query!( - " - INSERT INTO payouts_values (user_id, mod_id, amount, created) - VALUES ($1, $2, $3, $4) - ", - user_id, - id, - payout, - start - ) - .execute(&mut *transaction) - .await?; + insert_user_ids.push(user_id); + insert_project_ids.push(id); + insert_payouts.push(payout); + insert_starts.push(start); sqlx::query!( " @@ -528,6 +522,19 @@ pub async fn process_payout( } } + sqlx::query!( + " + INSERT INTO payouts_values (user_id, mod_id, amount, created) + SELECT * FROM UNNEST ($1::bigint[], $2::bigint[], $3::numeric[], $4::timestamptz[]) + ", + &insert_user_ids[..], + &insert_project_ids[..], + &insert_payouts[..], + &insert_starts[..] + ) + .execute(&mut *transaction) + .await?; + if !clear_cache_users.is_empty() { crate::database::models::User::clear_caches( &clear_cache_users diff --git a/src/routes/analytics.rs b/src/routes/analytics.rs index c4610c4e..36efdde0 100644 --- a/src/routes/analytics.rs +++ b/src/routes/analytics.rs @@ -150,7 +150,7 @@ pub async fn page_view_ingest( view.user_id = user.id.0; } - analytics_queue.add_view(view).await; + analytics_queue.add_view(view); Ok(HttpResponse::NoContent().body("")) } @@ -202,19 +202,17 @@ pub async fn playtime_ingest( } if let Some(version) = versions.iter().find(|x| id == x.inner.id.into()) { - analytics_queue - .add_playtime(Playtime { - id: Default::default(), - recorded: get_current_tenths_of_ms(), - seconds: playtime.seconds as u64, - user_id: user.id.0, - project_id: version.inner.project_id.0 as u64, - version_id: version.inner.id.0 as u64, - loader: playtime.loader, - game_version: playtime.game_version, - parent: playtime.parent.map(|x| x.0).unwrap_or(0), - }) - .await; + analytics_queue.add_playtime(Playtime { + id: Default::default(), + recorded: get_current_tenths_of_ms(), + seconds: playtime.seconds as u64, + user_id: user.id.0, + project_id: version.inner.project_id.0 as u64, + version_id: version.inner.id.0 as u64, + loader: playtime.loader, + game_version: playtime.game_version, + parent: playtime.parent.map(|x| x.0).unwrap_or(0), + }); } } diff --git a/src/routes/v2/admin.rs b/src/routes/v2/admin.rs index 69d7cb5c..cc5bd9e6 100644 --- a/src/routes/v2/admin.rs +++ b/src/routes/v2/admin.rs @@ -118,40 +118,36 @@ pub async fn count_download( let ip = crate::routes::analytics::convert_to_ip_v6(&download_body.ip) .unwrap_or_else(|_| Ipv4Addr::new(127, 0, 0, 1).to_ipv6_mapped()); - analytics_queue - .add_download(Download { - id: Uuid::new_v4(), + analytics_queue.add_download(Download { + id: Uuid::new_v4(), recorded: get_current_tenths_of_ms(), - domain: url.host_str().unwrap_or_default().to_string(), - site_path: url.path().to_string(), - user_id: user - .and_then(|(scopes, x)| { - if scopes.contains(Scopes::PERFORM_ANALYTICS) { - Some(x.id.0 as u64) - } else { - None - } - }) - .unwrap_or(0), - project_id: project_id as u64, - version_id: version_id as u64, - ip, - country: maxmind.query(ip).await.unwrap_or_default(), - user_agent: download_body - .headers - .get("user-agent") - .cloned() - .unwrap_or_default(), - headers: download_body - .headers - .clone() - .into_iter() - .filter(|x| { - !crate::routes::analytics::FILTERED_HEADERS.contains(&&*x.0.to_lowercase()) - }) - .collect(), - }) - .await; + domain: url.host_str().unwrap_or_default().to_string(), + site_path: url.path().to_string(), + user_id: user + .and_then(|(scopes, x)| { + if scopes.contains(Scopes::PERFORM_ANALYTICS) { + Some(x.id.0 as u64) + } else { + None + } + }) + .unwrap_or(0), + project_id: project_id as u64, + version_id: version_id as u64, + ip, + country: maxmind.query(ip).await.unwrap_or_default(), + user_agent: download_body + .headers + .get("user-agent") + .cloned() + .unwrap_or_default(), + headers: download_body + .headers + .clone() + .into_iter() + .filter(|x| !crate::routes::analytics::FILTERED_HEADERS.contains(&&*x.0.to_lowercase())) + .collect(), + }); Ok(HttpResponse::NoContent().body("")) } diff --git a/src/routes/v2/collections.rs b/src/routes/v2/collections.rs index 01372b0e..89778754 100644 --- a/src/routes/v2/collections.rs +++ b/src/routes/v2/collections.rs @@ -15,6 +15,7 @@ use crate::{database, models}; use actix_web::web::Data; use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse}; use chrono::Utc; +use itertools::Itertools; use serde::{Deserialize, Serialize}; use sqlx::PgPool; use std::sync::Arc; @@ -301,6 +302,11 @@ pub async fn collection_edit( .execute(&mut *transaction) .await?; + let collection_item_ids = new_project_ids + .iter() + .map(|_| collection_item.id.0) + .collect_vec(); + let mut validated_project_ids = Vec::new(); for project_id in new_project_ids { let project = database::models::Project::get(project_id, &**pool, &redis) .await? @@ -309,20 +315,20 @@ pub async fn collection_edit( "The specified project {project_id} does not exist!" )) })?; - - // Insert- don't throw an error if it already exists - sqlx::query!( - " - INSERT INTO collections_mods (collection_id, mod_id) - VALUES ($1, $2) - ON CONFLICT DO NOTHING - ", - collection_item.id as database::models::ids::CollectionId, - project.inner.id as database::models::ids::ProjectId, - ) - .execute(&mut *transaction) - .await?; + validated_project_ids.push(project.inner.id.0); } + // Insert- don't throw an error if it already exists + sqlx::query!( + " + INSERT INTO collections_mods (collection_id, mod_id) + SELECT * FROM UNNEST ($1::int8[], $2::int8[]) + ON CONFLICT DO NOTHING + ", + &collection_item_ids[..], + &validated_project_ids[..], + ) + .execute(&mut *transaction) + .await?; } database::models::Collection::clear_cache(collection_item.id, &redis).await?; diff --git a/src/routes/v2/projects.rs b/src/routes/v2/projects.rs index 50967487..1a0e4c69 100644 --- a/src/routes/v2/projects.rs +++ b/src/routes/v2/projects.rs @@ -2,6 +2,7 @@ use crate::auth::{filter_authorized_projects, get_user_from_headers, is_authoriz use crate::database; use crate::database::models::image_item; use crate::database::models::notification_item::NotificationBuilder; +use crate::database::models::project_item::{GalleryItem, ModCategory}; use crate::database::models::thread_item::ThreadMessageBuilder; use crate::database::redis::RedisPool; use crate::file_hosting::FileHost; @@ -31,6 +32,9 @@ use sqlx::PgPool; use std::sync::Arc; use validator::Validate; +use database::models as db_models; +use db_models::ids as db_ids; + pub fn config(cfg: &mut web::ServiceConfig) { cfg.service(project_search); cfg.service(projects_get); @@ -97,11 +101,11 @@ pub async fn random_projects_get( .collect::>(), ) .fetch_many(&**pool) - .try_filter_map(|e| async { Ok(e.right().map(|m| database::models::ids::ProjectId(m.id))) }) + .try_filter_map(|e| async { Ok(e.right().map(|m| db_ids::ProjectId(m.id))) }) .try_collect::>() .await?; - let projects_data = database::models::Project::get_many_ids(&project_ids, &**pool, &redis) + let projects_data = db_models::Project::get_many_ids(&project_ids, &**pool, &redis) .await? .into_iter() .map(Project::from) @@ -124,7 +128,7 @@ pub async fn projects_get( session_queue: web::Data, ) -> Result { let ids = serde_json::from_str::>(&ids.ids)?; - let projects_data = database::models::Project::get_many(&ids, &**pool, &redis).await?; + let projects_data = db_models::Project::get_many(&ids, &**pool, &redis).await?; let user_option = get_user_from_headers( &req, @@ -152,7 +156,7 @@ pub async fn project_get( ) -> Result { let string = info.into_inner().0; - let project_data = database::models::Project::get(&string, &**pool, &redis).await?; + let project_data = db_models::Project::get(&string, &**pool, &redis).await?; let user_option = get_user_from_headers( &req, &**pool, @@ -181,7 +185,7 @@ pub async fn project_get_check( ) -> Result { let slug = info.into_inner().0; - let project_data = database::models::Project::get(&slug, &**pool, &redis).await?; + let project_data = db_models::Project::get(&slug, &**pool, &redis).await?; if let Some(project) = project_data { Ok(HttpResponse::Ok().json(json! ({ @@ -208,7 +212,7 @@ pub async fn dependency_list( ) -> Result { let string = info.into_inner().0; - let result = database::models::Project::get(&string, &**pool, &redis).await?; + let result = db_models::Project::get(&string, &**pool, &redis).await?; let user_option = get_user_from_headers( &req, @@ -247,7 +251,7 @@ pub async fn dependency_list( let dep_version_ids = dependencies .iter() .filter_map(|x| x.0) - .collect::>(); + .collect::>(); let (projects_result, versions_result) = futures::future::try_join( database::Project::get_many_ids(&project_ids, &**pool, &redis), database::Version::get_many(&dep_version_ids, &**pool, &redis), @@ -399,13 +403,13 @@ pub async fn project_edit( .map_err(|err| ApiError::Validation(validation_errors_to_string(err, None)))?; let string = info.into_inner().0; - let result = database::models::Project::get(&string, &**pool, &redis).await?; + let result = db_models::Project::get(&string, &**pool, &redis).await?; if let Some(project_item) = result { let id = project_item.inner.id; let (team_member, organization_team_member) = - database::models::TeamMember::get_for_project_permissions( + db_models::TeamMember::get_for_project_permissions( &project_item.inner, user.id.into(), &**pool, @@ -436,7 +440,7 @@ pub async fn project_edit( WHERE (id = $2) ", title.trim(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -457,7 +461,7 @@ pub async fn project_edit( WHERE (id = $2) ", description, - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -494,7 +498,7 @@ pub async fn project_edit( SET moderation_message = NULL, moderation_message_body = NULL, queued = NOW() WHERE (id = $1) ", - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -505,7 +509,7 @@ pub async fn project_edit( SET show_in_mod_inbox = FALSE WHERE id = $1 ", - project_item.thread_id as database::models::ids::ThreadId, + project_item.thread_id as db_ids::ThreadId, ) .execute(&mut *transaction) .await?; @@ -518,7 +522,7 @@ pub async fn project_edit( SET approved = NOW() WHERE id = $1 AND approved IS NULL ", - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -542,7 +546,7 @@ pub async fn project_edit( SET webhook_sent = TRUE WHERE id = $1 ", - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -580,12 +584,10 @@ pub async fn project_edit( FROM team_members tm WHERE tm.team_id = $1 AND tm.accepted ", - project_item.inner.team_id as database::models::ids::TeamId + project_item.inner.team_id as db_ids::TeamId ) .fetch_many(&mut *transaction) - .try_filter_map(|e| async { - Ok(e.right().map(|c| database::models::UserId(c.id))) - }) + .try_filter_map(|e| async { Ok(e.right().map(|c| db_models::UserId(c.id))) }) .try_collect::>() .await?; @@ -618,7 +620,7 @@ pub async fn project_edit( WHERE (id = $2) ", status.as_str(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -652,7 +654,7 @@ pub async fn project_edit( WHERE (id = $2) ", requested_status.map(|x| x.as_str()), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -665,7 +667,7 @@ pub async fn project_edit( DELETE FROM mods_categories WHERE joining_mod_id = $1 AND is_additional = FALSE ", - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -677,7 +679,7 @@ pub async fn project_edit( DELETE FROM mods_categories WHERE joining_mod_id = $1 AND is_additional = TRUE ", - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -685,67 +687,25 @@ pub async fn project_edit( } if let Some(categories) = &new_project.categories { - if !perms.contains(ProjectPermissions::EDIT_DETAILS) { - return Err(ApiError::CustomAuthentication( - "You do not have the permissions to edit the categories of this project!" - .to_string(), - )); - } - - for category in categories { - let category_id = - database::models::categories::Category::get_id(category, &mut *transaction) - .await? - .ok_or_else(|| { - ApiError::InvalidInput(format!( - "Category {} does not exist.", - category.clone() - )) - })?; - - sqlx::query!( - " - INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional) - VALUES ($1, $2, FALSE) - ", - id as database::models::ids::ProjectId, - category_id as database::models::ids::CategoryId, - ) - .execute(&mut *transaction) - .await?; - } + edit_project_categories( + categories, + &perms, + id as db_ids::ProjectId, + false, + &mut transaction, + ) + .await?; } if let Some(categories) = &new_project.additional_categories { - if !perms.contains(ProjectPermissions::EDIT_DETAILS) { - return Err(ApiError::CustomAuthentication( - "You do not have the permissions to edit the additional categories of this project!" - .to_string(), - )); - } - - for category in categories { - let category_id = - database::models::categories::Category::get_id(category, &mut *transaction) - .await? - .ok_or_else(|| { - ApiError::InvalidInput(format!( - "Category {} does not exist.", - category.clone() - )) - })?; - - sqlx::query!( - " - INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional) - VALUES ($1, $2, TRUE) - ", - id as database::models::ids::ProjectId, - category_id as database::models::ids::CategoryId, - ) - .execute(&mut *transaction) - .await?; - } + edit_project_categories( + categories, + &perms, + id as db_ids::ProjectId, + true, + &mut transaction, + ) + .await?; } if let Some(issues_url) = &new_project.issues_url { @@ -763,7 +723,7 @@ pub async fn project_edit( WHERE (id = $2) ", issues_url.as_deref(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -784,7 +744,7 @@ pub async fn project_edit( WHERE (id = $2) ", source_url.as_deref(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -805,7 +765,7 @@ pub async fn project_edit( WHERE (id = $2) ", wiki_url.as_deref(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -826,7 +786,7 @@ pub async fn project_edit( WHERE (id = $2) ", license_url.as_deref(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -847,7 +807,7 @@ pub async fn project_edit( WHERE (id = $2) ", discord_url.as_deref(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -905,7 +865,7 @@ pub async fn project_edit( WHERE (id = $2) ", Some(slug), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -919,12 +879,10 @@ pub async fn project_edit( )); } - let side_type_id = database::models::categories::SideType::get_id( - new_side.as_str(), - &mut *transaction, - ) - .await? - .expect("No database entry found for side type"); + let side_type_id = + db_models::categories::SideType::get_id(new_side.as_str(), &mut *transaction) + .await? + .expect("No database entry found for side type"); sqlx::query!( " @@ -932,8 +890,8 @@ pub async fn project_edit( SET client_side = $1 WHERE (id = $2) ", - side_type_id as database::models::SideTypeId, - id as database::models::ids::ProjectId, + side_type_id as db_models::SideTypeId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -947,12 +905,10 @@ pub async fn project_edit( )); } - let side_type_id = database::models::categories::SideType::get_id( - new_side.as_str(), - &mut *transaction, - ) - .await? - .expect("No database entry found for side type"); + let side_type_id = + db_models::categories::SideType::get_id(new_side.as_str(), &mut *transaction) + .await? + .expect("No database entry found for side type"); sqlx::query!( " @@ -960,8 +916,8 @@ pub async fn project_edit( SET server_side = $1 WHERE (id = $2) ", - side_type_id as database::models::SideTypeId, - id as database::models::ids::ProjectId, + side_type_id as db_models::SideTypeId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -992,7 +948,7 @@ pub async fn project_edit( WHERE (id = $2) ", license, - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1010,13 +966,13 @@ pub async fn project_edit( DELETE FROM mods_donations WHERE joining_mod_id = $1 ", - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; for donation in donations { - let platform_id = database::models::categories::DonationPlatform::get_id( + let platform_id = db_models::categories::DonationPlatform::get_id( &donation.id, &mut *transaction, ) @@ -1033,8 +989,8 @@ pub async fn project_edit( INSERT INTO mods_donations (joining_mod_id, joining_platform_id, url) VALUES ($1, $2, $3) ", - id as database::models::ids::ProjectId, - platform_id as database::models::ids::DonationPlatformId, + id as db_ids::ProjectId, + platform_id as db_ids::DonationPlatformId, donation.url ) .execute(&mut *transaction) @@ -1059,7 +1015,7 @@ pub async fn project_edit( WHERE (id = $2) ", moderation_message.as_deref(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1083,7 +1039,7 @@ pub async fn project_edit( WHERE (id = $2) ", moderation_message_body.as_deref(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1104,7 +1060,7 @@ pub async fn project_edit( WHERE (id = $2) ", body, - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1136,7 +1092,7 @@ pub async fn project_edit( WHERE (id = $2) ", monetization_status.as_str(), - id as database::models::ids::ProjectId, + id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1154,7 +1110,7 @@ pub async fn project_edit( }; img::delete_unused_images(context, checkable_strings, &mut transaction, &redis).await?; - database::models::Project::clear_cache( + db_models::Project::clear_cache( project_item.inner.id, project_item.inner.slug, None, @@ -1174,6 +1130,13 @@ pub async fn project_edit( } } +#[derive(derive_new::new)] +pub struct CategoryChanges<'a> { + pub categories: &'a Option>, + pub add_categories: &'a Option>, + pub remove_categories: &'a Option>, +} + #[derive(Deserialize, Validate)] pub struct BulkEditProject { #[validate(length(max = 3))] @@ -1260,14 +1223,12 @@ pub async fn projects_edit( .validate() .map_err(|err| ApiError::Validation(validation_errors_to_string(err, None)))?; - let project_ids: Vec = - serde_json::from_str::>(&ids.ids)? - .into_iter() - .map(|x| x.into()) - .collect(); + let project_ids: Vec = serde_json::from_str::>(&ids.ids)? + .into_iter() + .map(|x| x.into()) + .collect(); - let projects_data = - database::models::Project::get_many_ids(&project_ids, &**pool, &redis).await?; + let projects_data = db_models::Project::get_many_ids(&project_ids, &**pool, &redis).await?; if let Some(id) = project_ids .iter() @@ -1282,31 +1243,27 @@ pub async fn projects_edit( let team_ids = projects_data .iter() .map(|x| x.inner.team_id) - .collect::>(); + .collect::>(); let team_members = - database::models::TeamMember::get_from_team_full_many(&team_ids, &**pool, &redis).await?; + db_models::TeamMember::get_from_team_full_many(&team_ids, &**pool, &redis).await?; let organization_ids = projects_data .iter() .filter_map(|x| x.inner.organization_id) - .collect::>(); + .collect::>(); let organizations = - database::models::Organization::get_many_ids(&organization_ids, &**pool, &redis).await?; + db_models::Organization::get_many_ids(&organization_ids, &**pool, &redis).await?; let organization_team_ids = organizations .iter() .map(|x| x.team_id) - .collect::>(); - let organization_team_members = database::models::TeamMember::get_from_team_full_many( - &organization_team_ids, - &**pool, - &redis, - ) - .await?; + .collect::>(); + let organization_team_members = + db_models::TeamMember::get_from_team_full_many(&organization_team_ids, &**pool, &redis) + .await?; - let categories = database::models::categories::Category::list(&**pool, &redis).await?; - let donation_platforms = - database::models::categories::DonationPlatform::list(&**pool, &redis).await?; + let categories = db_models::categories::Category::list(&**pool, &redis).await?; + let donation_platforms = db_models::categories::DonationPlatform::list(&**pool, &redis).await?; let mut transaction = pool.begin().await?; @@ -1356,126 +1313,35 @@ pub async fn projects_edit( }; } - let mut set_categories = if let Some(categories) = bulk_edit_project.categories.clone() { - categories - } else { - project.categories.clone() - }; - - if let Some(delete_categories) = &bulk_edit_project.remove_categories { - for category in delete_categories { - if let Some(pos) = set_categories.iter().position(|x| x == category) { - set_categories.remove(pos); - } - } - } - - if let Some(add_categories) = &bulk_edit_project.add_categories { - for category in add_categories { - if set_categories.len() < 3 { - set_categories.push(category.clone()); - } else { - break; - } - } - } - - if set_categories != project.categories { - sqlx::query!( - " - DELETE FROM mods_categories - WHERE joining_mod_id = $1 AND is_additional = FALSE - ", - project.inner.id as database::models::ids::ProjectId, - ) - .execute(&mut *transaction) - .await?; - - for category in set_categories { - let category_id = categories - .iter() - .find(|x| x.category == category) - .ok_or_else(|| { - ApiError::InvalidInput(format!( - "Category {} does not exist.", - category.clone() - )) - })? - .id; - - sqlx::query!( - " - INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional) - VALUES ($1, $2, FALSE) - ", - project.inner.id as database::models::ids::ProjectId, - category_id as database::models::ids::CategoryId, - ) - .execute(&mut *transaction) - .await?; - } - } - - let mut set_additional_categories = - if let Some(categories) = bulk_edit_project.additional_categories.clone() { - categories - } else { - project.additional_categories.clone() - }; - - if let Some(delete_categories) = &bulk_edit_project.remove_additional_categories { - for category in delete_categories { - if let Some(pos) = set_additional_categories.iter().position(|x| x == category) { - set_additional_categories.remove(pos); - } - } - } - - if let Some(add_categories) = &bulk_edit_project.add_additional_categories { - for category in add_categories { - if set_additional_categories.len() < 256 { - set_additional_categories.push(category.clone()); - } else { - break; - } - } - } - - if set_additional_categories != project.additional_categories { - sqlx::query!( - " - DELETE FROM mods_categories - WHERE joining_mod_id = $1 AND is_additional = TRUE - ", - project.inner.id as database::models::ids::ProjectId, - ) - .execute(&mut *transaction) - .await?; - - for category in set_additional_categories { - let category_id = categories - .iter() - .find(|x| x.category == category) - .ok_or_else(|| { - ApiError::InvalidInput(format!( - "Category {} does not exist.", - category.clone() - )) - })? - .id; + bulk_edit_project_categories( + &categories, + &project.categories, + project.inner.id as db_ids::ProjectId, + CategoryChanges::new( + &bulk_edit_project.categories, + &bulk_edit_project.add_categories, + &bulk_edit_project.remove_categories, + ), + 3, + false, + &mut transaction, + ) + .await?; - sqlx::query!( - " - INSERT INTO mods_categories (joining_mod_id, joining_category_id, is_additional) - VALUES ($1, $2, TRUE) - ", - project.inner.id as database::models::ids::ProjectId, - category_id as database::models::ids::CategoryId, - ) - .execute(&mut *transaction) - .await?; - } - } + bulk_edit_project_categories( + &categories, + &project.additional_categories, + project.inner.id as db_ids::ProjectId, + CategoryChanges::new( + &bulk_edit_project.additional_categories, + &bulk_edit_project.add_additional_categories, + &bulk_edit_project.remove_additional_categories, + ), + 256, + true, + &mut transaction, + ) + .await?; let project_donations: Vec = project .donation_urls @@ -1514,7 +1380,7 @@ pub async fn projects_edit( DELETE FROM mods_donations WHERE joining_mod_id = $1 ", - project.inner.id as database::models::ids::ProjectId, + project.inner.id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1536,8 +1402,8 @@ pub async fn projects_edit( INSERT INTO mods_donations (joining_mod_id, joining_platform_id, url) VALUES ($1, $2, $3) ", - project.inner.id as database::models::ids::ProjectId, - platform_id as database::models::ids::DonationPlatformId, + project.inner.id as db_ids::ProjectId, + platform_id as db_ids::DonationPlatformId, donation.url ) .execute(&mut *transaction) @@ -1553,7 +1419,7 @@ pub async fn projects_edit( WHERE (id = $2) ", issues_url.as_deref(), - project.inner.id as database::models::ids::ProjectId, + project.inner.id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1567,7 +1433,7 @@ pub async fn projects_edit( WHERE (id = $2) ", source_url.as_deref(), - project.inner.id as database::models::ids::ProjectId, + project.inner.id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1581,7 +1447,7 @@ pub async fn projects_edit( WHERE (id = $2) ", wiki_url.as_deref(), - project.inner.id as database::models::ids::ProjectId, + project.inner.id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -1595,14 +1461,13 @@ pub async fn projects_edit( WHERE (id = $2) ", discord_url.as_deref(), - project.inner.id as database::models::ids::ProjectId, + project.inner.id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; } - database::models::Project::clear_cache(project.inner.id, project.inner.slug, None, &redis) - .await?; + db_models::Project::clear_cache(project.inner.id, project.inner.slug, None, &redis).await?; } transaction.commit().await?; @@ -1610,6 +1475,96 @@ pub async fn projects_edit( Ok(HttpResponse::NoContent().body("")) } +pub async fn bulk_edit_project_categories( + all_db_categories: &[db_models::categories::Category], + project_categories: &Vec, + project_id: db_ids::ProjectId, + bulk_changes: CategoryChanges<'_>, + max_num_categories: usize, + is_additional: bool, + transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, +) -> Result<(), ApiError> { + let mut set_categories = if let Some(categories) = bulk_changes.categories.clone() { + categories + } else { + project_categories.clone() + }; + + if let Some(delete_categories) = &bulk_changes.remove_categories { + for category in delete_categories { + if let Some(pos) = set_categories.iter().position(|x| x == category) { + set_categories.remove(pos); + } + } + } + + if let Some(add_categories) = &bulk_changes.add_categories { + for category in add_categories { + if set_categories.len() < max_num_categories { + set_categories.push(category.clone()); + } else { + break; + } + } + } + + if &set_categories != project_categories { + sqlx::query!( + " + DELETE FROM mods_categories + WHERE joining_mod_id = $1 AND is_additional = $2 + ", + project_id as db_ids::ProjectId, + is_additional + ) + .execute(&mut *transaction) + .await?; + + let mut mod_categories = Vec::new(); + for category in set_categories { + let category_id = all_db_categories + .iter() + .find(|x| x.category == category) + .ok_or_else(|| { + ApiError::InvalidInput(format!("Category {} does not exist.", category.clone())) + })? + .id; + mod_categories.push(ModCategory::new(project_id, category_id, is_additional)); + } + ModCategory::insert_many(mod_categories, &mut *transaction).await?; + } + + Ok(()) +} + +pub async fn edit_project_categories( + categories: &Vec, + perms: &ProjectPermissions, + project_id: db_ids::ProjectId, + additional: bool, + transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>, +) -> Result<(), ApiError> { + if !perms.contains(ProjectPermissions::EDIT_DETAILS) { + let additional_str = if additional { "additional " } else { "" }; + return Err(ApiError::CustomAuthentication(format!( + "You do not have the permissions to edit the {additional_str}categories of this project!" + ))); + } + + let mut mod_categories = Vec::new(); + for category in categories { + let category_id = db_models::categories::Category::get_id(category, &mut *transaction) + .await? + .ok_or_else(|| { + ApiError::InvalidInput(format!("Category {} does not exist.", category.clone())) + })?; + mod_categories.push(ModCategory::new(project_id, category_id, additional)); + } + ModCategory::insert_many(mod_categories, &mut *transaction).await?; + + Ok(()) +} + #[derive(Deserialize)] pub struct SchedulingData { pub time: DateTime, @@ -1648,11 +1603,11 @@ pub async fn project_schedule( } let string = info.into_inner().0; - let result = database::models::Project::get(&string, &**pool, &redis).await?; + let result = db_models::Project::get(&string, &**pool, &redis).await?; if let Some(project_item) = result { let (team_member, organization_team_member) = - database::models::TeamMember::get_for_project_permissions( + db_models::TeamMember::get_for_project_permissions( &project_item.inner, user.id.into(), &**pool, @@ -1692,12 +1647,12 @@ pub async fn project_schedule( ", ProjectStatus::Scheduled.as_str(), scheduling_data.time, - project_item.inner.id as database::models::ids::ProjectId, + project_item.inner.id as db_ids::ProjectId, ) .execute(&**pool) .await?; - database::models::Project::clear_cache( + db_models::Project::clear_cache( project_item.inner.id, project_item.inner.slug, None, @@ -1741,7 +1696,7 @@ pub async fn project_icon_edit( .1; let string = info.into_inner().0; - let project_item = database::models::Project::get(&string, &**pool, &redis) + let project_item = db_models::Project::get(&string, &**pool, &redis) .await? .ok_or_else(|| { ApiError::InvalidInput("The specified project does not exist!".to_string()) @@ -1749,7 +1704,7 @@ pub async fn project_icon_edit( if !user.role.is_mod() { let (team_member, organization_team_member) = - database::models::TeamMember::get_for_project_permissions( + db_models::TeamMember::get_for_project_permissions( &project_item.inner, user.id.into(), &**pool, @@ -1810,12 +1765,12 @@ pub async fn project_icon_edit( ", format!("{}/{}", cdn_url, upload_data.file_name), color.map(|x| x as i32), - project_item.inner.id as database::models::ids::ProjectId, + project_item.inner.id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; - database::models::Project::clear_cache( + db_models::Project::clear_cache( project_item.inner.id, project_item.inner.slug, None, @@ -1854,7 +1809,7 @@ pub async fn delete_project_icon( .1; let string = info.into_inner().0; - let project_item = database::models::Project::get(&string, &**pool, &redis) + let project_item = db_models::Project::get(&string, &**pool, &redis) .await? .ok_or_else(|| { ApiError::InvalidInput("The specified project does not exist!".to_string()) @@ -1862,7 +1817,7 @@ pub async fn delete_project_icon( if !user.role.is_mod() { let (team_member, organization_team_member) = - database::models::TeamMember::get_for_project_permissions( + db_models::TeamMember::get_for_project_permissions( &project_item.inner, user.id.into(), &**pool, @@ -1906,18 +1861,13 @@ pub async fn delete_project_icon( SET icon_url = NULL, color = NULL WHERE (id = $1) ", - project_item.inner.id as database::models::ids::ProjectId, + project_item.inner.id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; - database::models::Project::clear_cache( - project_item.inner.id, - project_item.inner.slug, - None, - &redis, - ) - .await?; + db_models::Project::clear_cache(project_item.inner.id, project_item.inner.slug, None, &redis) + .await?; transaction.commit().await?; @@ -1963,7 +1913,7 @@ pub async fn add_gallery_item( .1; let string = info.into_inner().0; - let project_item = database::models::Project::get(&string, &**pool, &redis) + let project_item = db_models::Project::get(&string, &**pool, &redis) .await? .ok_or_else(|| { ApiError::InvalidInput("The specified project does not exist!".to_string()) @@ -1977,7 +1927,7 @@ pub async fn add_gallery_item( if !user.role.is_admin() { let (team_member, organization_team_member) = - database::models::TeamMember::get_for_project_permissions( + db_models::TeamMember::get_for_project_permissions( &project_item.inner, user.id.into(), &**pool, @@ -2040,25 +1990,24 @@ pub async fn add_gallery_item( SET featured = $2 WHERE mod_id = $1 ", - project_item.inner.id as database::models::ids::ProjectId, + project_item.inner.id as db_ids::ProjectId, false, ) .execute(&mut *transaction) .await?; } - database::models::project_item::GalleryItem { + let gallery_item = vec![db_models::project_item::GalleryItem { image_url: file_url, featured: item.featured, title: item.title, description: item.description, created: Utc::now(), ordering: item.ordering.unwrap_or(0), - } - .insert(project_item.inner.id, &mut transaction) - .await?; + }]; + GalleryItem::insert_many(gallery_item, project_item.inner.id, &mut transaction).await?; - database::models::Project::clear_cache( + db_models::Project::clear_cache( project_item.inner.id, project_item.inner.slug, None, @@ -2122,7 +2071,7 @@ pub async fn edit_gallery_item( item.validate() .map_err(|err| ApiError::Validation(validation_errors_to_string(err, None)))?; - let project_item = database::models::Project::get(&string, &**pool, &redis) + let project_item = db_models::Project::get(&string, &**pool, &redis) .await? .ok_or_else(|| { ApiError::InvalidInput("The specified project does not exist!".to_string()) @@ -2130,7 +2079,7 @@ pub async fn edit_gallery_item( if !user.role.is_mod() { let (team_member, organization_team_member) = - database::models::TeamMember::get_for_project_permissions( + db_models::TeamMember::get_for_project_permissions( &project_item.inner, user.id.into(), &**pool, @@ -2185,7 +2134,7 @@ pub async fn edit_gallery_item( SET featured = $2 WHERE mod_id = $1 ", - project_item.inner.id as database::models::ids::ProjectId, + project_item.inner.id as db_ids::ProjectId, false, ) .execute(&mut *transaction) @@ -2244,13 +2193,8 @@ pub async fn edit_gallery_item( .await?; } - database::models::Project::clear_cache( - project_item.inner.id, - project_item.inner.slug, - None, - &redis, - ) - .await?; + db_models::Project::clear_cache(project_item.inner.id, project_item.inner.slug, None, &redis) + .await?; transaction.commit().await?; @@ -2283,7 +2227,7 @@ pub async fn delete_gallery_item( .1; let string = info.into_inner().0; - let project_item = database::models::Project::get(&string, &**pool, &redis) + let project_item = db_models::Project::get(&string, &**pool, &redis) .await? .ok_or_else(|| { ApiError::InvalidInput("The specified project does not exist!".to_string()) @@ -2291,7 +2235,7 @@ pub async fn delete_gallery_item( if !user.role.is_mod() { let (team_member, organization_team_member) = - database::models::TeamMember::get_for_project_permissions( + db_models::TeamMember::get_for_project_permissions( &project_item.inner, user.id.into(), &**pool, @@ -2356,13 +2300,8 @@ pub async fn delete_gallery_item( .execute(&mut *transaction) .await?; - database::models::Project::clear_cache( - project_item.inner.id, - project_item.inner.slug, - None, - &redis, - ) - .await?; + db_models::Project::clear_cache(project_item.inner.id, project_item.inner.slug, None, &redis) + .await?; transaction.commit().await?; @@ -2389,7 +2328,7 @@ pub async fn project_delete( .1; let string = info.into_inner().0; - let project = database::models::Project::get(&string, &**pool, &redis) + let project = db_models::Project::get(&string, &**pool, &redis) .await? .ok_or_else(|| { ApiError::InvalidInput("The specified project does not exist!".to_string()) @@ -2397,7 +2336,7 @@ pub async fn project_delete( if !user.role.is_admin() { let (team_member, organization_team_member) = - database::models::TeamMember::get_for_project_permissions( + db_models::TeamMember::get_for_project_permissions( &project.inner, user.id.into(), &**pool, @@ -2429,8 +2368,7 @@ pub async fn project_delete( let context = ImageContext::Project { project_id: Some(project.inner.id.into()), }; - let uploaded_images = - database::models::Image::get_many_contexted(context, &mut transaction).await?; + let uploaded_images = db_models::Image::get_many_contexted(context, &mut transaction).await?; for image in uploaded_images { image_item::Image::remove(image.id, &mut transaction, &redis).await?; } @@ -2440,13 +2378,12 @@ pub async fn project_delete( DELETE FROM collections_mods WHERE mod_id = $1 ", - project.inner.id as database::models::ids::ProjectId, + project.inner.id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; - let result = - database::models::Project::remove(project.inner.id, &mut transaction, &redis).await?; + let result = db_models::Project::remove(project.inner.id, &mut transaction, &redis).await?; transaction.commit().await?; @@ -2478,14 +2415,14 @@ pub async fn project_follow( .1; let string = info.into_inner().0; - let result = database::models::Project::get(&string, &**pool, &redis) + let result = db_models::Project::get(&string, &**pool, &redis) .await? .ok_or_else(|| { ApiError::InvalidInput("The specified project does not exist!".to_string()) })?; - let user_id: database::models::ids::UserId = user.id.into(); - let project_id: database::models::ids::ProjectId = result.inner.id; + let user_id: db_ids::UserId = user.id.into(); + let project_id: db_ids::ProjectId = result.inner.id; if !is_authorized(&result.inner, &Some(user), &pool).await? { return Ok(HttpResponse::NotFound().body("")); @@ -2495,8 +2432,8 @@ pub async fn project_follow( " SELECT EXISTS(SELECT 1 FROM mod_follows mf WHERE mf.follower_id = $1 AND mf.mod_id = $2) ", - user_id as database::models::ids::UserId, - project_id as database::models::ids::ProjectId + user_id as db_ids::UserId, + project_id as db_ids::ProjectId ) .fetch_one(&**pool) .await? @@ -2512,7 +2449,7 @@ pub async fn project_follow( SET follows = follows + 1 WHERE id = $1 ", - project_id as database::models::ids::ProjectId, + project_id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -2522,8 +2459,8 @@ pub async fn project_follow( INSERT INTO mod_follows (follower_id, mod_id) VALUES ($1, $2) ", - user_id as database::models::ids::UserId, - project_id as database::models::ids::ProjectId + user_id as db_ids::UserId, + project_id as db_ids::ProjectId ) .execute(&mut *transaction) .await?; @@ -2557,21 +2494,21 @@ pub async fn project_unfollow( .1; let string = info.into_inner().0; - let result = database::models::Project::get(&string, &**pool, &redis) + let result = db_models::Project::get(&string, &**pool, &redis) .await? .ok_or_else(|| { ApiError::InvalidInput("The specified project does not exist!".to_string()) })?; - let user_id: database::models::ids::UserId = user.id.into(); + let user_id: db_ids::UserId = user.id.into(); let project_id = result.inner.id; let following = sqlx::query!( " SELECT EXISTS(SELECT 1 FROM mod_follows mf WHERE mf.follower_id = $1 AND mf.mod_id = $2) ", - user_id as database::models::ids::UserId, - project_id as database::models::ids::ProjectId + user_id as db_ids::UserId, + project_id as db_ids::ProjectId ) .fetch_one(&**pool) .await? @@ -2587,7 +2524,7 @@ pub async fn project_unfollow( SET follows = follows - 1 WHERE id = $1 ", - project_id as database::models::ids::ProjectId, + project_id as db_ids::ProjectId, ) .execute(&mut *transaction) .await?; @@ -2597,8 +2534,8 @@ pub async fn project_unfollow( DELETE FROM mod_follows WHERE follower_id = $1 AND mod_id = $2 ", - user_id as database::models::ids::UserId, - project_id as database::models::ids::ProjectId + user_id as db_ids::UserId, + project_id as db_ids::ProjectId ) .execute(&mut *transaction) .await?; diff --git a/src/routes/v2/version_creation.rs b/src/routes/v2/version_creation.rs index 80fc895d..9c7b8611 100644 --- a/src/routes/v2/version_creation.rs +++ b/src/routes/v2/version_creation.rs @@ -725,9 +725,7 @@ async fn upload_file_to_version_inner( "At least one file must be specified".to_string(), )); } else { - for file_builder in file_builders { - file_builder.insert(version_id, &mut *transaction).await?; - } + VersionFileBuilder::insert_many(file_builders, version_id, &mut *transaction).await?; } // Clear version cache diff --git a/src/routes/v2/versions.rs b/src/routes/v2/versions.rs index cfaa9da4..218706e9 100644 --- a/src/routes/v2/versions.rs +++ b/src/routes/v2/versions.rs @@ -3,6 +3,7 @@ use crate::auth::{ filter_authorized_versions, get_user_from_headers, is_authorized, is_authorized_version, }; use crate::database; +use crate::database::models::version_item::{DependencyBuilder, LoaderVersion, VersionVersion}; use crate::database::models::{image_item, Organization}; use crate::database::redis::RedisPool; use crate::models; @@ -450,11 +451,12 @@ pub async fn version_edit( }) .collect::>(); - for dependency in builders { - dependency - .insert(version_item.inner.id, &mut transaction) - .await?; - } + DependencyBuilder::insert_many( + builders, + version_item.inner.id, + &mut transaction, + ) + .await?; } } } @@ -469,6 +471,7 @@ pub async fn version_edit( .execute(&mut *transaction) .await?; + let mut version_versions = Vec::new(); for game_version in game_versions { let game_version_id = database::models::categories::GameVersion::get_id( &game_version.0, @@ -481,17 +484,9 @@ pub async fn version_edit( ) })?; - sqlx::query!( - " - INSERT INTO game_versions_versions (game_version_id, joining_version_id) - VALUES ($1, $2) - ", - game_version_id as database::models::ids::GameVersionId, - id as database::models::ids::VersionId, - ) - .execute(&mut *transaction) - .await?; + version_versions.push(VersionVersion::new(game_version_id, id)); } + VersionVersion::insert_many(version_versions, &mut transaction).await?; database::models::Project::update_game_versions( version_item.inner.project_id, @@ -510,6 +505,7 @@ pub async fn version_edit( .execute(&mut *transaction) .await?; + let mut loader_versions = Vec::new(); for loader in loaders { let loader_id = database::models::categories::Loader::get_id(&loader.0, &mut *transaction) @@ -519,18 +515,9 @@ pub async fn version_edit( "No database entry for loader provided.".to_string(), ) })?; - - sqlx::query!( - " - INSERT INTO loaders_versions (loader_id, version_id) - VALUES ($1, $2) - ", - loader_id as database::models::ids::LoaderId, - id as database::models::ids::VersionId, - ) - .execute(&mut *transaction) - .await?; + loader_versions.push(LoaderVersion::new(loader_id, id)); } + LoaderVersion::insert_many(loader_versions, &mut transaction).await?; database::models::Project::update_loaders( version_item.inner.project_id, diff --git a/tests/common/database.rs b/tests/common/database.rs index 63535125..483a44d9 100644 --- a/tests/common/database.rs +++ b/tests/common/database.rs @@ -29,6 +29,7 @@ pub const USER_USER_PAT: &str = "mrp_patuser"; pub const FRIEND_USER_PAT: &str = "mrp_patfriend"; pub const ENEMY_USER_PAT: &str = "mrp_patenemy"; +#[derive(Clone)] pub struct TemporaryDatabase { pub pool: PgPool, pub redis_pool: RedisPool, @@ -75,10 +76,14 @@ impl TemporaryDatabase { .await .expect("Connection to temporary database failed"); + println!("Running migrations on temporary database"); + // Performs migrations let migrations = sqlx::migrate!("./migrations"); migrations.run(&pool).await.expect("Migrations failed"); + println!("Migrations complete"); + // Gets new Redis pool let redis_pool = RedisPool::new(Some(temp_database_name.clone())); diff --git a/tests/common/dummy_data.rs b/tests/common/dummy_data.rs index d3cd9667..35cdc97d 100644 --- a/tests/common/dummy_data.rs +++ b/tests/common/dummy_data.rs @@ -13,6 +13,16 @@ use super::{ environment::TestEnvironment, }; +pub const DUMMY_CATEGORIES: &'static [&str] = &[ + "combat", + "decoration", + "economy", + "food", + "magic", + "mobs", + "optimization", +]; + pub struct DummyData { pub alpha_team_id: String, pub beta_team_id: String, diff --git a/tests/common/environment.rs b/tests/common/environment.rs index bcf5c686..cba05836 100644 --- a/tests/common/environment.rs +++ b/tests/common/environment.rs @@ -3,6 +3,19 @@ use super::{database::TemporaryDatabase, dummy_data}; use crate::common::setup; use actix_web::{dev::ServiceResponse, test, App}; +use futures::Future; + +pub async fn with_test_environment(f: impl FnOnce(TestEnvironment) -> Fut) +where + Fut: Future, +{ + let test_env = TestEnvironment::build_with_dummy().await; + let db = test_env.db.clone(); + + f(test_env).await; + + db.cleanup().await; +} // A complete test environment, with a test actix app and a database. // Must be called in an #[actix_rt::test] context. It also simulates a diff --git a/tests/files/dummy_data.sql b/tests/files/dummy_data.sql index 59391f48..0583f8af 100644 --- a/tests/files/dummy_data.sql +++ b/tests/files/dummy_data.sql @@ -27,10 +27,20 @@ INSERT INTO loaders (id, loader) VALUES (1, 'fabric'); INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id) VALUES (1,1); INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id) VALUES (1,2); -INSERT INTO categories (id, category, project_type) VALUES (1, 'combat', 1); -INSERT INTO categories (id, category, project_type) VALUES (2, 'decoration', 1); -INSERT INTO categories (id, category, project_type) VALUES (3, 'economy', 1); +INSERT INTO categories (id, category, project_type) VALUES + (1, 'combat', 1), + (2, 'decoration', 1), + (3, 'economy', 1), + (4, 'food', 1), + (5, 'magic', 1), + (6, 'mobs', 1), + (7, 'optimization', 1); -INSERT INTO categories (id, category, project_type) VALUES (4, 'combat', 2); -INSERT INTO categories (id, category, project_type) VALUES (5, 'decoration', 2); -INSERT INTO categories (id, category, project_type) VALUES (6, 'economy', 2); \ No newline at end of file +INSERT INTO categories (id, category, project_type) VALUES + (101, 'combat', 2), + (102, 'decoration', 2), + (103, 'economy', 2), + (104, 'food', 2), + (105, 'magic', 2), + (106, 'mobs', 2), + (107, 'optimization', 2); \ No newline at end of file diff --git a/tests/project.rs b/tests/project.rs index 215bcb66..c28804f9 100644 --- a/tests/project.rs +++ b/tests/project.rs @@ -1,10 +1,14 @@ +use actix_http::StatusCode; +use actix_web::dev::ServiceResponse; use actix_web::test; +use common::environment::with_test_environment; use labrinth::database::models::project_item::{PROJECTS_NAMESPACE, PROJECTS_SLUGS_NAMESPACE}; use labrinth::models::ids::base62_impl::parse_base62; use serde_json::json; use crate::common::database::*; +use crate::common::dummy_data::DUMMY_CATEGORIES; use crate::common::{actix::AppendsMultipart, environment::TestEnvironment}; // importing common module. @@ -403,7 +407,7 @@ pub async fn test_patch_project() { "title": "New successful title", "description": "New successful description", "body": "New successful body", - "categories": ["combat"], + "categories": [DUMMY_CATEGORIES[0]], "license_id": "MIT", "issues_url": "https://github.com", "discord_url": "https://discord.gg", @@ -441,7 +445,7 @@ pub async fn test_patch_project() { assert_eq!(body["title"], json!("New successful title")); assert_eq!(body["description"], json!("New successful description")); assert_eq!(body["body"], json!("New successful body")); - assert_eq!(body["categories"], json!(["combat"])); + assert_eq!(body["categories"], json!([DUMMY_CATEGORIES[0]])); assert_eq!(body["license"]["id"], json!("MIT")); assert_eq!(body["issues_url"], json!("https://github.com")); assert_eq!(body["discord_url"], json!("https://discord.gg")); @@ -457,5 +461,68 @@ pub async fn test_patch_project() { test_env.cleanup().await; } +#[actix_rt::test] +pub async fn test_bulk_edit_categories() { + with_test_environment(|test_env| async move { + let alpha_project_id = &test_env.dummy.as_ref().unwrap().alpha_project_id; + let beta_project_id = &test_env.dummy.as_ref().unwrap().beta_project_id; + + let req = test::TestRequest::patch() + .uri(&format!( + "/v2/projects?ids={}", + urlencoding::encode(&format!("[\"{alpha_project_id}\",\"{beta_project_id}\"]")) + )) + .append_header(("Authorization", ADMIN_USER_PAT)) + .set_json(json!({ + "categories": [DUMMY_CATEGORIES[0], DUMMY_CATEGORIES[3]], + "add_categories": [DUMMY_CATEGORIES[1], DUMMY_CATEGORIES[2]], + "remove_categories": [DUMMY_CATEGORIES[3]], + "additional_categories": [DUMMY_CATEGORIES[4], DUMMY_CATEGORIES[6]], + "add_additional_categories": [DUMMY_CATEGORIES[5]], + "remove_additional_categories": [DUMMY_CATEGORIES[6]], + })) + .to_request(); + let resp = test_env.call(req).await; + assert_eq!(resp.status(), StatusCode::NO_CONTENT); + + let alpha_body = get_project_body(&test_env, &alpha_project_id, ADMIN_USER_PAT).await; + assert_eq!(alpha_body["categories"], json!(DUMMY_CATEGORIES[0..=2])); + assert_eq!( + alpha_body["additional_categories"], + json!(DUMMY_CATEGORIES[4..=5]) + ); + + let beta_body = get_project_body(&test_env, &beta_project_id, ADMIN_USER_PAT).await; + assert_eq!(beta_body["categories"], alpha_body["categories"]); + assert_eq!( + beta_body["additional_categories"], + alpha_body["additional_categories"], + ); + }) + .await; +} + +async fn get_project( + test_env: &TestEnvironment, + project_slug: &str, + user_pat: &str, +) -> ServiceResponse { + let req = test::TestRequest::get() + .uri(&format!("/v2/project/{project_slug}")) + .append_header(("Authorization", user_pat)) + .to_request(); + test_env.call(req).await +} + +async fn get_project_body( + test_env: &TestEnvironment, + project_slug: &str, + user_pat: &str, +) -> serde_json::Value { + let resp = get_project(test_env, project_slug, user_pat).await; + assert_eq!(resp.status(), StatusCode::OK); + test::read_body_json(resp).await +} + // TODO: Missing routes on projects // TODO: using permissions/scopes, can we SEE projects existence that we are not allowed to? (ie 401 instead of 404)