import { type QueryDefinitions, validatedDefinitions } from './querytypes.js'; import { boolean, discordSnowflake, jsonArray, nullable, string, substring, tableIdentifierOrId, tableIdentifierSubstring, timestamp, URL } from './validators.js'; import { guaranteedSingleton, jsonParser, nothing, rows, singleton, writeCount } from './transformers.js'; export const DatabaseQueries = validatedDefinitions({ autocompleteTable: { query: `WITH matchingIds (id) AS (SELECT DISTINCT rollableTableIdentifiers.tableId AS id FROM rollableTableIdentifiers WHERE rollableTableIdentifiers.identifier LIKE ?1 ESCAPE '\\' UNION SELECT DISTINCT rollableTableHeaders.tableId AS id FROM rollableTableHeaders WHERE rollableTableHeaders.header LIKE ?1 ESCAPE '\\' UNION SELECT DISTINCT rollableTableBadges.id AS id FROM rollableTableBadges WHERE rollableTableBadges.badge LIKE ?1 ESCAPE '\\') SELECT rollableTables.identifier AS identifier, rollableTables.name AS name, rollableTables.emoji AS emoji FROM rollableTables WHERE ?1 = '%' OR rollableTables.id IN matchingIds LIMIT 25;`, parameters: { 'tableIdentifierSubstring': { validator: tableIdentifierSubstring, index: 1 } }, output: rows<{ identifier: string, name: string, emoji: string }>() }, autocompleteTextForDiscordSet: { query: `WITH matchingTables (id) AS (SELECT DISTINCT rollableTableIdentifiers.tableId AS id FROM rollableTableIdentifiers WHERE rollableTableIdentifiers.identifier LIKE ?2 ESCAPE '\\' UNION SELECT DISTINCT rollableTableHeaders.tableId AS id FROM rollableTableHeaders WHERE rollableTableHeaders.header LIKE ?2 ESCAPE '\\' UNION SELECT DISTINCT rollableTableBadges.id AS id FROM rollableTableBadges WHERE rollableTableBadges.badge LIKE ?2 ESCAPE '\\'), rollableSets (id) AS (SELECT resultSets.id FROM resultSets WHERE (?4 AND resultSets.global) OR resultSets.discordSnowflake = ?1) SELECT rollableResults.text AS text FROM rollableResults WHERE rollableResults.tableId IN matchingTables AND EXISTS(SELECT resultMappings.resultId FROM resultMappings WHERE resultMappings.setId IN rollableSets AND resultMappings.resultId = rollableResults.id) AND (?3 = '%' OR rollableResults.text LIKE ?3 ESCAPE '\\') ORDER BY (rollableResults.text LIKE SUBSTR(1, ?3) ESCAPE '\\') DESC, LENGTH(rollableResults.text) LIMIT 25;`, parameters: { 'setSnowflake': { validator: discordSnowflake, index: 1 }, 'tableIdentifierSubstring': { validator: tableIdentifierSubstring, index: 2 }, 'pattern': { validator: substring, index: 3 }, 'includeGlobal': { validator: boolean, index: 4 } }, output: rows<{ text: string }>() }, addResultForAddMapping: { query: `WITH rollableTable (id) AS (SELECT rollableTableIdentifiers.tableId FROM rollableTableIdentifiers WHERE (rollableTableIdentifiers.identifier = ?1 OR rollableTableIdentifiers.tableId = ?1)) INSERT OR IGNORE INTO rollableResults (tableId, text) VALUES ((SELECT rollableTable.id FROM rollableTable), ?2);`, parameters: { 'tableIdentifier': { validator: tableIdentifierOrId, index: 1 }, 'text': { validator: string, index: 2 } }, output: nothing() }, addDiscordAuthorForAddMapping: { query: `WITH authorshipType (id) AS (SELECT authorshipTypes.id FROM authorshipTypes WHERE authorshipTypes.name = 'Discord contributor') INSERT INTO authors (name, url, discordSnowflake, discordUsername, authorshipTypeId) VALUES (NULL, NULL, ?1, ?2, (SELECT authorshipType.id FROM authorshipType)) ON CONFLICT DO UPDATE SET discordUsername = ?2;`, parameters: { 'userSnowflake': { validator: discordSnowflake, index: 1 }, 'username': { validator: string, index: 2 } }, output: nothing() }, addDiscordSetForAddMapping: { query: `INSERT OR IGNORE INTO resultSets (name, description, discordSnowflake, creatorId, global) VALUES (NULL, NULL, ?1, (SELECT authors.id FROM authors WHERE authors.discordSnowflake = ?2), FALSE)`, parameters: { 'setSnowflake': { validator: discordSnowflake, index: 1 }, 'userSnowflake': { validator: discordSnowflake, index: 2 } }, output: nothing() }, addDiscordResultMapping: { query: `WITH rollableTable (id) AS (SELECT rollableTableIdentifiers.tableId FROM rollableTableIdentifiers WHERE rollableTableIdentifiers.identifier = ?2 OR rollableTableIdentifiers.tableId = ?2 LIMIT 1), rollableResult (id) AS (SELECT rollableResults.id FROM rollableResults WHERE rollableResults.text = ?3 AND rollableResults.tableId = (SELECT id FROM rollableTable) LIMIT 1), resultSet (id) AS (SELECT resultSets.id FROM resultSets WHERE resultSets.discordSnowflake = ?5 AND NOT resultSets.global LIMIT 1), author (id) AS (SELECT authors.id FROM authors WHERE authors.discordSnowflake = ?4 LIMIT 1) INSERT OR IGNORE INTO resultMappings (resultId, setId, authorId, created, updated) VALUES ((SELECT rollableResult.id FROM rollableResult), (SELECT resultSet.id FROM resultSet), (SELECT author.id FROM author), ?1, ?1);`, parameters: { 'timestamp': { validator: timestamp, index: 1 }, 'tableIdentifier': { validator: tableIdentifierOrId, index: 2 }, 'resultText': { validator: string, index: 3 }, 'userSnowflake': { validator: discordSnowflake, index: 4 }, 'setSnowflake': { validator: discordSnowflake, index: 5 } }, output: nothing() }, getResultMappingsForDiscordSet: { query: `WITH rollableTable (id) AS (SELECT rollableTableIdentifiers.tableId FROM rollableTableIdentifiers WHERE rollableTableIdentifiers.identifier = ?2 OR rollableTableIdentifiers.tableId = ?2 LIMIT 1), visibleSets (id) AS (SELECT resultSets.id FROM resultSets WHERE ((?5 AND resultSets.global) OR resultSets.discordSnowflake = ?4)) SELECT resultMappings.id AS mappingId, rollableResults.id AS resultId, rollableResults.text AS resultText, authors.id AS authorId, COALESCE(authors.name, authorshipTypes.defaultAuthor) AS authorName, authors.url AS authorUrl, authorshipTypes.relationPrefix AS authorRelation, resultSets.id AS setId, resultSets.name AS setName, resultSets.description AS setDescription, resultSets.global AS setGlobal, rollableTables.id AS tableId, rollableTables.identifier AS tableIdentifier, rollableTables.name AS tableName, rollableTables.title AS tableTitle, rollableTables.emoji AS tableEmoji, rollableTables.header AS tableHeader, rollableTables.ordinal AS tableOrdinal, resultMappings.updated AS updated, (CASE WHEN resultMappings.updated = ?1 THEN 'updated' ELSE 'existing' END) AS status FROM resultMappings INNER JOIN rollableResults ON rollableResults.id = resultMappings.resultId LEFT JOIN authors ON authors.id = resultMappings.authorId LEFT JOIN authorshipTypes ON authorshipTypes.id = authors.authorshipTypeId INNER JOIN resultSets ON resultSets.id = resultMappings.setId INNER JOIN rollableTables ON rollableTables.id = rollableResults.tableId WHERE rollableResults.tableId = (SELECT id FROM rollableTable) AND rollableResults.text = ?3 AND resultMappings.setId IN visibleSets ORDER BY (NOT setGlobal) DESC, (authorId IS NOT NULL) DESC, updated, mappingId;`, parameters: { 'timestamp': { validator: nullable(timestamp), index: 1 }, 'tableIdentifier': { validator: tableIdentifierOrId, index: 2 }, 'text': { validator: string, index: 3 }, 'setSnowflake': { validator: discordSnowflake, index: 4 }, 'includeGlobal': { validator: boolean, index: 5 } }, output: rows<{ mappingId: number, resultId: number, resultText: string, authorId: number | null, authorName: string | null, authorUrl: string | null, authorRelation: string | null, setId: number, setName: string | null, setDescription: string | null, setGlobal: number, tableId: number, tableIdentifier: string, tableName: string, tableTitle: string, tableEmoji: string, tableHeader: string, tableOrdinal: number, updated: number, status: 'updated' | 'existing' }>() }, addResultForEditMapping: { query: `WITH rollableTable(id) AS (SELECT rollableTableIdentifiers.tableId FROM rollableTableIdentifiers WHERE (rollableTableIdentifiers.identifier = ?1 OR rollableTableIdentifiers.tableId = ?1) LIMIT 1), oldResult (id) AS (SELECT rollableResults.id FROM rollableResults WHERE rollableResults.tableId = (SELECT rollableTable.id FROM rollableTable) AND rollableResults.text = ?2 LIMIT 1), targetSet (id) AS (SELECT resultSets.id FROM resultSets WHERE resultSets.discordSnowflake = ?4 LIMIT 1) INSERT OR IGNORE INTO rollableResults (tableId, text) SELECT rollableTable.id, ?3 FROM rollableTable WHERE ?2 != ?3 AND EXISTS (SELECT resultMappings.id FROM resultMappings WHERE resultMappings.resultId = (SELECT oldResult.id FROM oldResult) AND resultMappings.setId = (SELECT targetSet.id FROM targetSet));`, parameters: { 'tableIdentifier': { validator: tableIdentifierOrId, index: 1 }, 'oldText': { validator: string, index: 2 }, 'newText': { validator: string, index: 3 }, 'setSnowflake': { validator: discordSnowflake, index: 4 } }, output: nothing() }, addDiscordAuthorForEditMapping: { query: `WITH authorshipType (id) AS (SELECT authorshipTypes.id FROM authorshipTypes WHERE authorshipTypes.name = 'Discord contributor' LIMIT 1), rollableTable (id) AS (SELECT rollableTableIdentifiers.tableId FROM rollableTableIdentifiers WHERE rollableTableIdentifiers.identifier = ?3 OR rollableTableIdentifiers.tableId = ?3 LIMIT 1), oldResult (id) AS (SELECT rollableResults.id FROM rollableResults WHERE rollableResults.tableId = (SELECT rollableTable.id FROM rollableTable) AND rollableResults.text = ?4 LIMIT 1), newResult (id) AS (SELECT rollableResults.id FROM rollableResults WHERE rollableResults.tableId = (SELECT rollableTable.id FROM rollableTable) AND rollableResults.text = ?5 LIMIT 1), targetSet (id) AS (SELECT resultSets.id FROM resultSets WHERE resultSets.discordSnowflake = ?6 LIMIT 1) INSERT INTO authors (name, url, discordSnowflake, discordUsername, authorshipTypeId) SELECT NULL AS name, NULL AS url, ?1 AS discordSnowflake, ?2 AS discordUsername, authorshipType.id AS authorshipTypeId FROM authorshipType WHERE ?4 != ?5 AND EXISTS (SELECT resultMappings.id FROM resultMappings WHERE resultMappings.resultId = (SELECT oldResult.id FROM oldResult) AND resultMappings.setId = (SELECT targetSet.id FROM targetSet)) AND NOT EXISTS (SELECT resultMappings.id FROM resultMappings WHERE resultMappings.resultId = (SELECT newResult.id FROM newResult) AND resultMappings.setId = (SELECT targetSet.id FROM targetSet)) ON CONFLICT DO UPDATE SET discordUsername = ?2;`, parameters: { 'userSnowflake': { validator: discordSnowflake, index: 1 }, 'username': { validator: string, index: 2 }, 'tableIdentifier': { validator: tableIdentifierOrId, index: 3 }, 'oldText': { validator: string, index: 4 }, 'newText': { validator: string, index: 5 }, 'setSnowflake': { validator: discordSnowflake, index: 6 } }, output: nothing() }, editMappingForDiscord: { query: `WITH rollableTable (id) AS (SELECT rollableTableIdentifiers.tableId FROM rollableTableIdentifiers WHERE rollableTableIdentifiers.identifier = ?2 OR rollableTableIdentifiers.tableId = ?2 LIMIT 1), oldResult (id) AS (SELECT rollableResults.id FROM rollableResults WHERE rollableResults.tableId = (SELECT rollableTable.id FROM rollableTable) AND rollableResults.text = ?3 LIMIT 1), newResult(id) AS (SELECT rollableResults.id FROM rollableResults WHERE rollableResults.tableId = (SELECT rollableTable.id FROM rollableTable) AND rollableResults.text = ?4 LIMIT 1), author(id) AS (SELECT authors.id FROM authors WHERE authors.discordSnowflake = ?5 LIMIT 1), targetSet(id) AS (SELECT resultSets.id FROM resultSets WHERE resultSets.discordSnowflake = ?6 AND NOT resultSets.global LIMIT 1) UPDATE OR IGNORE resultMappings SET resultId = (SELECT id FROM newResult), authorId = (SELECT id FROM author), updated = ?1 WHERE ?3 != ?4 AND resultMappings.resultId = (SELECT id FROM oldResult) AND resultMappings.setId = (SELECT id FROM targetSet);`, parameters: { 'timestamp': { validator: timestamp, index: 1 }, 'tableIdentifier': { validator: tableIdentifierOrId, index: 2 }, 'oldText': { validator: string, index: 3 }, 'newText': { validator: string, index: 4 }, 'userSnowflake': { validator: discordSnowflake, index: 5 }, 'setSnowflake': { validator: discordSnowflake, index: 6 } }, output: nothing() }, deleteDiscordResultMapping: { query: `WITH rollableTable (id) AS (SELECT rollableTableIdentifiers.tableId FROM rollableTableIdentifiers WHERE rollableTableIdentifiers.identifier = ?1 OR rollableTableIdentifiers.tableId = ?1 LIMIT 1), oldResult (id) AS (SELECT rollableResults.id FROM rollableResults WHERE rollableResults.tableId = (SELECT rollableTable.id FROM rollableTable) AND rollableResults.text = ?2 LIMIT 1), targetSet(id) AS (SELECT resultSets.id FROM resultSets WHERE resultSets.discordSnowflake = ?3 AND NOT resultSets.global LIMIT 1) DELETE FROM resultMappings WHERE resultId = (SELECT oldResult.id FROM oldResult) AND setId = (SELECT targetSet.id FROM targetSet);`, parameters: { 'tableIdentifier': { validator: tableIdentifierOrId, index: 1 }, 'text': { validator: string, index: 2 }, 'setSnowflake': { validator: discordSnowflake, index: 3 } }, output: writeCount() }, generateFromDiscord: { query: `WITH originalResults (tableId, header, ordinal, text) AS (SELECT rollableTables.id AS tableId, rollableTables.header AS header, rollableTables.ordinal AS ordinal, NULL AS text FROM rollableTables WHERE ?3 IS NULL UNION ALL SELECT rollableTableHeaders.tableId AS id, original.value ->> '$[0]' AS header, original.key AS ordinal, original.value ->> '$[1]' AS text FROM json_each(COALESCE(?3, '[]')) original LEFT JOIN rollableTableHeaders ON rollableTableHeaders.header = (original.value ->> '$[0]') ORDER BY ordinal), selection (tableId) AS (SELECT COALESCE(rollableTableIdentifiers.tableId, rollableTableHeaders.tableId) AS tableId FROM json_each(COALESCE(?4, '[]')) selection LEFT JOIN rollableTableIdentifiers ON rollableTableIdentifiers.identifier = selection.value LEFT JOIN rollableTableHeaders ON rollableTableHeaders.header = selection.value WHERE COALESCE(rollableTableIdentifiers.tableId, rollableTableHeaders.tableId) IS NOT NULL), visibleSets (id, global) AS (SELECT resultSets.id, resultSets.global FROM resultSets WHERE (resultSets.global OR resultSets.discordSnowflake = ?2)), usedResults (id) AS (SELECT DISTINCT resultMappings.resultId FROM resultMappings WHERE resultMappings.setId IN (SELECT id FROM visibleSets)), usedTables (id) AS (SELECT DISTINCT rollableResults.tableId FROM usedResults INNER JOIN rollableResults ON rollableResults.id = usedResults.id), usedMappings (id) AS (SELECT (SELECT resultMappings.id FROM resultMappings WHERE resultMappings.resultId = usedResults.id AND resultMappings.setId IN (SELECT id FROM visibleSets) ORDER BY (NOT visibleSets.global) DESC, (resultMappings.authorId IS NOT NULL) DESC, updated LIMIT 1) FROM usedResults), usedAuthors (id) AS (SELECT DISTINCT resultMappings.authorId FROM usedMappings INNER JOIN resultMappings ON resultMappings.id = usedMappings.id), usedSets (id) AS (SELECT DISTINCT resultMappings.setId FROM usedMappings INNER JOIN resultMappings ON resultMappings.id = usedMappings.id), results (resultId, tableId, header, ordinal, originalText) AS (SELECT (SELECT rollableResults.id FROM rollableResults WHERE rollableResults.tableId = originalResult.tableId AND rollableResults.id IN usedResults AND ((?1 AND (originalResult.text IS NULL OR ?4 IS NULL OR originalResult.tableId IN selection)) OR rollableResults.text = originalResult.text) ORDER BY RANDOM() LIMIT 1) AS resultId, originalResult.tableId AS tableId, originalResult.header AS header, originalResult.ordinal AS ordinal, originalResult.text AS originalText FROM originalResults AS originalResult) SELECT resultMappings.id AS mappingId, rollableResults.id AS resultId, COALESCE(rollableResults.text, results.originalText, '') AS resultText, authors.id AS authorId, COALESCE(authors.name, authorshipTypes.defaultAuthor) AS authorName, authors.url AS authorUrl, authorshipTypes.relationPrefix AS authorRelation, resultSets.id AS setId, resultSets.name AS setName, resultSets.description AS setDescription, resultSets.global AS setGlobal, rollableTables.id AS tableId, rollableTables.identifier AS tableIdentifier, rollableTables.name AS tableName, COALESCE( rollableTables.title, SUBSTR(results.header, INSTR(results.header, ' ') + 1)) AS tableTitle, COALESCE( rollableTables.emoji, SUBSTR(results.header, 1, INSTR(results.header, ' ') - 1)) AS tableEmoji, results.header AS tableHeader, results.ordinal AS tableOrdinal, resultMappings.updated AS updated, results.tableId IN selection AS selected FROM results LEFT JOIN rollableResults ON rollableResults.id = results.resultId LEFT JOIN rollableTables ON rollableTables.id = results.tableId LEFT JOIN resultMappings ON resultMappings.id = (SELECT resultMappings.id FROM resultMappings INNER JOIN visibleSets ON visibleSets.id = resultMappings.setId WHERE resultMappings.resultId = results.resultId ORDER BY (NOT visibleSets.global) DESC, (resultMappings.authorId IS NOT NULL) DESC, updated LIMIT 1) LEFT JOIN authors ON authors.id = resultMappings.authorId LEFT JOIN authorshipTypes ON authorshipTypes.id = authors.authorshipTypeId LEFT JOIN resultSets ON resultSets.id = resultMappings.setId;`, parameters: { 'reroll': { validator: boolean, index: 1 }, 'setSnowflake': { validator: nullable(discordSnowflake), index: 2 }, 'original': { validator: nullable(jsonArray), index: 3 }, 'selection': { validator: nullable(jsonArray), index: 4 } }, output: rows<{ mappingId: null, resultId: null, resultText: string, authorId: null, authorName: null, authorUrl: null, authorRelation: null, setId: null, setName: null, setDescription: null, setGlobal: null, tableId: null, tableIdentifier: null, tableName: null, tableTitle: string, tableEmoji: string, tableHeader: string, tableOrdinal: number, updated: null, selected: false; } | { mappingId: null, resultId: null, resultText: string, authorId: null, authorName: null, authorUrl: null, authorRelation: null, setId: null, setName: null, setDescription: null, setGlobal: null, tableId: number, tableIdentifier: string, tableName: string, tableTitle: string, tableEmoji: string, tableHeader: string, tableOrdinal: number, updated: null, selected: boolean, } | { mappingId: number, resultId: number, resultText: string, authorId: number | null, authorName: string | null, authorUrl: string | null, authorRelation: string | null, setId: number, setName: string | null, setDescription: string | null, setGlobal: number, tableId: number, tableIdentifier: string, tableName: string, tableTitle: string, tableEmoji: string, tableHeader: string, tableOrdinal: number, updated: number, selected: boolean, }>() }, getDiscordAuthor: { query: ` SELECT authors.id AS id, COALESCE(authors.name, authorshipTypes.defaultAuthor) AS name, authors.url AS url, authorshipTypes.relationPrefix AS relation FROM authors INNER JOIN main.authorshipTypes authorshipTypes on authorshipTypes.id = authors.authorshipTypeId WHERE authors.discordSnowflake = ?1;`, parameters: { 'userSnowflake': { validator: discordSnowflake, index: 1 } }, output: singleton<{ id: number, name: string, url: string, relation: string }>() }, setDiscordAuthor: { query: ` INSERT INTO authors (discordSnowflake, discordUsername, name, url, authorshipTypeId) VALUES (?1, ?2, ?3, ?4, (SELECT authorshipTypes.id FROM authorshipTypes WHERE authorshipTypes.name = 'Discord contributor')) ON CONFLICT DO UPDATE SET discordUsername = ?2, name = ?3, url = ?4;`, parameters: { 'userSnowflake': { validator: discordSnowflake, index: 1 }, 'username': { validator: string, index: 2 }, 'name': { validator: nullable(string), index: 3 }, 'url': { validator: nullable(URL), index: 4 } }, output: nothing() }, getFullDatabaseForDiscordSet: { query: `WITH originalResults (tableId, header, ordinal, text) AS (SELECT rollableTables.id AS tableId, rollableTables.header AS header, rollableTables.ordinal AS ordinal, NULL AS text FROM rollableTables WHERE ?3 IS NULL UNION ALL SELECT rollableTableHeaders.tableId AS id, original.value ->> '$[0]' AS header, original.key AS ordinal, original.value ->> '$[1]' AS text FROM json_each(COALESCE(?3, '[]')) original LEFT JOIN rollableTableHeaders ON rollableTableHeaders.header = (original.value ->> '$[0]') ORDER BY ordinal), selection (tableId) AS (SELECT COALESCE(rollableTableIdentifiers.tableId, rollableTableHeaders.tableId) AS tableId FROM json_each(COALESCE(?4, '[]')) selection LEFT JOIN rollableTableIdentifiers ON rollableTableIdentifiers.identifier = selection.value LEFT JOIN rollableTableHeaders ON rollableTableHeaders.header = selection.value WHERE COALESCE(rollableTableIdentifiers.tableId, rollableTableHeaders.tableId) IS NOT NULL), visibleSets (id, global) AS (SELECT resultSets.id, resultSets.global FROM resultSets WHERE (resultSets.global OR resultSets.discordSnowflake = ?2)), usedResults (id) AS (SELECT DISTINCT resultMappings.resultId FROM resultMappings WHERE resultMappings.setId IN (SELECT id FROM visibleSets)), usedTables (id) AS (SELECT DISTINCT rollableResults.tableId FROM usedResults INNER JOIN rollableResults ON rollableResults.id = usedResults.id), usedMappings (id) AS (SELECT (SELECT resultMappings.id FROM resultMappings INNER JOIN visibleSets ON resultMappings.setId = visibleSets.id WHERE resultMappings.resultId = usedResults.id ORDER BY (NOT visibleSets.global) DESC, (resultMappings.authorId IS NOT NULL) DESC, updated LIMIT 1) FROM usedResults), usedAuthors (id) AS (SELECT DISTINCT resultMappings.authorId FROM usedMappings INNER JOIN resultMappings ON resultMappings.id = usedMappings.id), usedSets (id) AS (SELECT DISTINCT resultMappings.setId FROM usedMappings INNER JOIN resultMappings ON resultMappings.id = usedMappings.id), generationResults (resultObj) AS (SELECT COALESCE((SELECT json_object( 'type', 'mapping', 'mappingId', resultMappings.id) FROM rollableResults INNER JOIN resultMappings ON resultMappings.resultId = rollableResults.id INNER JOIN usedMappings ON usedMappings.id = resultMappings.id WHERE rollableResults.tableId = originalResult.tableId AND rollableResults.id IN usedResults AND ((?1 AND (originalResult.text IS NULL OR ?4 IS NULL OR originalResult.tableId IN selection)) OR rollableResults.text = originalResult.text) ORDER BY RANDOM() LIMIT 1), CASE WHEN originalResult.tableId IN usedTables THEN json_object( 'type', 'unknownText', 'tableId', originalResult.tableId, 'text', originalResult.text) ELSE json_object( 'type', 'unknownTable', 'header', originalResult.header, 'title', SUBSTR(originalResult.header, INSTR(originalResult.header, ' ') + 1), 'emoji', SUBSTR(originalResult.header, 1, INSTR(originalResult.header, ' ') - 1), 'ordinal', originalResult.ordinal, 'text', originalResult.text) END) FROM originalResults AS originalResult WHERE ?1 OR (?3 IS NOT NULL)) SELECT (SELECT json_group_array(json(tableObj)) FROM (SELECT json_object('id', rollableTables.id, 'identifier', rollableTables.identifier, 'name', rollableTables.name, 'title', rollableTables.title, 'emoji', rollableTables.emoji, 'header', rollableTables.header, 'ordinal', rollableTables.ordinal, 'selected', CASE WHEN rollableTables.id IN selection THEN json('true') ELSE json('false') END) AS tableObj FROM usedTables INNER JOIN rollableTables ON rollableTables.id = usedTables.id)) AS tables, (SELECT json_group_array(json(setObj)) FROM (SELECT json_object('id', resultSets.id, 'name', resultSets.name, 'description', resultSets.description, 'global', CASE WHEN resultSets.global THEN json('true') ELSE json('false') END) AS setObj FROM usedSets INNER JOIN resultSets ON resultSets.id = usedSets.id)) AS sets, (SELECT json_group_array(json(authorObj)) FROM (SELECT json_object('id', authors.id, 'name', COALESCE(authors.name, authorshipTypes.defaultAuthor), 'url', authors.url, 'relation', authorshipTypes.relationPrefix) AS authorObj FROM usedAuthors INNER JOIN authors ON authors.id = usedAuthors.id INNER JOIN authorshipTypes ON authorshipTypes.id = authors.authorshipTypeId)) AS authors, (SELECT json_group_array(json(mappingObj)) FROM (SELECT json_object('mappingId', resultMappings.id, 'textId', resultMappings.resultId, 'text', rollableResults.text, 'tableId', rollableResults.tableId, 'setId', resultMappings.setId, 'authorId', resultMappings.authorId, 'updated', resultMappings.updated) AS mappingObj FROM usedMappings INNER JOIN resultMappings ON resultMappings.id = usedMappings.id INNER JOIN rollableResults ON rollableResults.id = resultMappings.resultId)) AS mappings, CASE WHEN EXISTS (SELECT resultObj FROM generationResults) THEN (SELECT json_group_array(json(resultObj)) FROM generationResults) ELSE json('null') END AS results;`, parameters: { 'reroll': { validator: boolean, index: 1 }, 'setSnowflake': { validator: nullable(discordSnowflake), index: 2 }, 'original': { validator: nullable(jsonArray), index: 3 }, 'selection': { validator: nullable(jsonArray), index: 4 } }, output: guaranteedSingleton(jsonParser<{ tables: { id: number, identifier: string, name: string, title: string, emoji: string, header: string, ordinal: number, selected: boolean }[] sets: { id: number, name: string | null, description: string | null, global: boolean }[], authors: { id: number, name: string, url: string | null, relation: string }[], mappings: { mappingId: number, textId: number, text: string, tableId: number, setId: number, authorId: number, updated: number }[], results: (({ type: 'mapping', mappingId: number } | { type: 'unknownText', tableId: number, text: string } | { type: 'unknownTable', header: string, title: string, emoji: string, ordinal: number, text: string })[]) | null }>(['tables', 'sets', 'authors', 'mappings', 'results'])) } } as const satisfies QueryDefinitions);