Scenario generator for vore roleplay and story ideas. https://scenario-generator.deliciousreya.net/responses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

614 lines
22 KiB

import { type QueryDefinitions, validatedDefinitions } from './querytypes';
import {
boolean,
discordSnowflake,
jsonArray,
nullable,
string,
substring,
tableIdentifierOrId,
tableIdentifierSubstring,
timestamp,
URL
} from './validators';
import { extract, guaranteedSingleton, jsonParser, nothing, rows, singleton, writeCount } from './transformers';
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()
},
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()
},
getTableIdsByIdentifierOrHeader: {
query: `SELECT COALESCE(rollableTableIdentifiers.tableId, rollableTableHeaders.tableId) AS id
FROM json_each(?1) selection
LEFT JOIN rollableTableIdentifiers
ON rollableTableIdentifiers.identifier = selection.value
LEFT JOIN rollableTableHeaders ON rollableTableHeaders.header = selection.value;`,
parameters: {
'identifiersOrHeaders': {
validator: jsonArray,
index: 1
}
},
output: rows(extract<number | null>("id"))
},
getTables: {
query: `SELECT id, identifier, name, title, emoji, header, ordinal
FROM rollableTables`,
parameters: {},
output: rows<{
id: number,
identifier: string,
name: string,
title: string,
emoji: string,
header: string,
ordinal: number
}>()
},
getFullDatabaseForDiscordSet: {
query: `WITH visibleSets (id, name, description, global)
AS (SELECT resultSets.id,
resultSets.name,
resultSets.description,
resultSets.global
FROM resultSets
WHERE (resultSets.global OR resultSets.discordSnowflake = ?1)),
visibleResults (mappingId, setId, textId, tableId, text, authorId, updated)
AS (SELECT resultMappings.id AS mappingId,
resultMappings.setId AS setId,
resultMappings.resultId AS textId,
rollableResults.tableId AS tableId,
rollableResults.text AS text,
resultMappings.authorId AS authorId,
resultMappings.updated AS updated
FROM resultMappings
INNER JOIN visibleSets ON resultMappings.setId = visibleSets.id
INNER JOIN rollableResults ON rollableResults.id = resultMappings.resultId),
visibleAuthors (id, name, url, relation)
AS (SELECT DISTINCT authors.id,
COALESCE(authors.name, authorshipTypes.defaultAuthor),
authors.url,
authorshipTypes.relationPrefix
FROM visibleResults
INNER JOIN authors ON authors.id = visibleResults.authorId
INNER JOIN authorshipTypes ON authorshipTypes.id = authors.authorshipTypeId)
SELECT (SELECT json_group_array(json_object('id', visibleSets.id,
'name', visibleSets.name,
'description', visibleSets.description,
'global', CASE
WHEN visibleSets.global THEN json('true')
ELSE json('false') END))
FROM visibleSets) AS sets,
(SELECT json_group_array(json_object('id', visibleAuthors.id,
'name', visibleAuthors.name,
'url', visibleAuthors.url,
'relation', visibleAuthors.relation))
FROM visibleAuthors) AS authors,
(SELECT json_group_array(json_object('mappingId', visibleResults.mappingId,
'textId', visibleResults.textId,
'text', visibleResults.text,
'tableId', visibleResults.tableId,
'setId', visibleResults.setId,
'authorId', visibleResults.authorId,
'updated', visibleResults.updated))
FROM visibleResults) AS mappings;`,
parameters: {
'setSnowflake': {
validator: nullable(discordSnowflake),
index: 1
}
},
output: guaranteedSingleton(jsonParser<{
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
}[],
}>(['sets', 'authors', 'mappings']))
}
} as const satisfies QueryDefinitions);