{ "version": 3, "sources": ["../../lib/database.ts"], "sourcesContent": ["/**\n * Database abstraction layer that's vaguely ORM-like.\n * Modern (Promises, strict types, tagged template literals), but ORMs\n * are a bit _too_ magical for me, so none of that magic here.\n *\n * @author Zarel\n */\n\nimport * as mysql from 'mysql2';\nimport * as pg from 'pg';\n\nexport type BasicSQLValue = string | number | null;\nexport type SQLRow = { [k: string]: BasicSQLValue };\nexport type SQLValue = BasicSQLValue | SQLStatement | PartialOrSQL | BasicSQLValue[] | undefined;\n\nexport function isSQL(value: any): value is SQLStatement {\n\t/**\n\t * This addresses a scenario where objects get out of sync due to hotpatching.\n\t * Table A is instantiated, and retains SQLStatement at that specific point in time. Consumer A is also instantiated at\n\t * the same time, and both can interact freely, since consumer A and table A share the same reference to SQLStatement.\n\t * However, when consumer A is hotpatched, consumer A imports a new instance of SQLStatement. Thus, when consumer A\n\t * provides that new SQLStatement, it does not pass the `instanceof SQLStatement` check in Table A,\n\t * since table A is still referencing he old SQLStatement (checking that the new is an instance of the old).\n\t * This does not work. Thus, we're forced to check constructor name instead.\n\t */\n\treturn value instanceof SQLStatement || (\n\t\t// assorted safety checks to be sure it'll actually work (theoretically preventing certain attacks)\n\t\tvalue?.constructor.name === 'SQLStatement' && (Array.isArray(value.sql) && Array.isArray(value.values))\n\t);\n}\n\nexport class SQLStatement {\n\tsql: string[];\n\tvalues: BasicSQLValue[];\n\tconstructor(strings: TemplateStringsArray, values: SQLValue[]) {\n\t\tthis.sql = [strings[0]];\n\t\tthis.values = [];\n\t\tfor (let i = 0; i < strings.length; i++) {\n\t\t\tthis.append(values[i], strings[i + 1]);\n\t\t}\n\t}\n\tappend(value: SQLValue, nextString = ''): this {\n\t\tif (isSQL(value)) {\n\t\t\tif (!value.sql.length) return this;\n\t\t\tconst oldLength = this.sql.length;\n\t\t\tthis.sql = this.sql.concat(value.sql.slice(1));\n\t\t\tthis.sql[oldLength - 1] += value.sql[0];\n\t\t\tthis.values = this.values.concat(value.values);\n\t\t\tif (nextString) this.sql[this.sql.length - 1] += nextString;\n\t\t} else if (typeof value === 'string' || typeof value === 'number' || value === null) {\n\t\t\tthis.values.push(value);\n\t\t\tthis.sql.push(nextString);\n\t\t} else if (value === undefined) {\n\t\t\tthis.sql[this.sql.length - 1] += nextString;\n\t\t} else if (Array.isArray(value)) {\n\t\t\tif ('\"`'.includes(this.sql[this.sql.length - 1].slice(-1))) {\n\t\t\t\t// \"`a`, `b`\" syntax\n\t\t\t\tconst quoteChar = this.sql[this.sql.length - 1].slice(-1);\n\t\t\t\tfor (const col of value) {\n\t\t\t\t\tthis.append(col, `${quoteChar}, ${quoteChar}`);\n\t\t\t\t}\n\t\t\t\tthis.sql[this.sql.length - 1] = this.sql[this.sql.length - 1].slice(0, -4) + nextString;\n\t\t\t} else {\n\t\t\t\t// \"1, 2\" syntax\n\t\t\t\tfor (const val of value) {\n\t\t\t\t\tthis.append(val, `, `);\n\t\t\t\t}\n\t\t\t\tthis.sql[this.sql.length - 1] = this.sql[this.sql.length - 1].slice(0, -2) + nextString;\n\t\t\t}\n\t\t} else if (this.sql[this.sql.length - 1].endsWith('(')) {\n\t\t\t// \"(`a`, `b`) VALUES (1, 2)\" syntax\n\t\t\tthis.sql[this.sql.length - 1] += `\"`;\n\t\t\tfor (const col in value) {\n\t\t\t\tthis.append(col, `\", \"`);\n\t\t\t}\n\t\t\tthis.sql[this.sql.length - 1] = this.sql[this.sql.length - 1].slice(0, -4) + `\") VALUES (`;\n\t\t\tfor (const col in value) {\n\t\t\t\tthis.append(value[col], `, `);\n\t\t\t}\n\t\t\tthis.sql[this.sql.length - 1] = this.sql[this.sql.length - 1].slice(0, -2) + nextString;\n\t\t} else if (this.sql[this.sql.length - 1].toUpperCase().endsWith(' SET ')) {\n\t\t\t// \"`a` = 1, `b` = 2\" syntax\n\t\t\tthis.sql[this.sql.length - 1] += `\"`;\n\t\t\tfor (const col in value) {\n\t\t\t\tthis.append(col, `\" = `);\n\t\t\t\tthis.append(value[col], `, \"`);\n\t\t\t}\n\t\t\tthis.sql[this.sql.length - 1] = this.sql[this.sql.length - 1].slice(0, -3) + nextString;\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`Objects can only appear in (obj) or after SET; ` +\n\t\t\t\t`unrecognized: ${this.sql[this.sql.length - 1]}[obj]${nextString}`\n\t\t\t);\n\t\t}\n\t\treturn this;\n\t}\n}\n\n/**\n * Tag function for SQL, with some magic.\n *\n * * `` SQL`UPDATE table SET a = ${'hello\"'}` ``\n * * `` `UPDATE table SET a = 'hello'` ``\n *\n * Values surrounded by `\"` or `` ` `` become identifiers:\n *\n * * ``` SQL`SELECT * FROM \"${'table'}\"` ```\n * * `` `SELECT * FROM \"table\"` ``\n *\n * (Make sure to use `\"` for Postgres and `` ` `` for MySQL.)\n *\n * Objects preceded by SET become setters:\n *\n * * `` SQL`UPDATE table SET ${{a: 1, b: 2}}` ``\n * * `` `UPDATE table SET \"a\" = 1, \"b\" = 2` ``\n *\n * Objects surrounded by `()` become keys and values:\n *\n * * `` SQL`INSERT INTO table (${{a: 1, b: 2}})` ``\n * * `` `INSERT INTO table (\"a\", \"b\") VALUES (1, 2)` ``\n *\n * Arrays become lists; surrounding by `\"` or `` ` `` turns them into lists of names:\n *\n * * `` SQL`INSERT INTO table (\"${['a', 'b']}\") VALUES (${[1, 2]})` ``\n * * `` `INSERT INTO table (\"a\", \"b\") VALUES (1, 2)` ``\n */\nexport function SQL(strings: TemplateStringsArray, ...values: SQLValue[]) {\n\treturn new SQLStatement(strings, values);\n}\n\nexport interface ResultRow { [k: string]: BasicSQLValue }\n\nexport const connectedDatabases: Database[] = [];\n\nexport abstract class Database {\n\tconnection: Pool;\n\tprefix: string;\n\ttype = '';\n\tconstructor(connection: Pool, prefix = '') {\n\t\tthis.prefix = prefix;\n\t\tthis.connection = connection;\n\t\tconnectedDatabases.push(this);\n\t}\n\tabstract _resolveSQL(query: SQLStatement): [query: string, values: BasicSQLValue[]];\n\tabstract _query(sql: string, values: BasicSQLValue[]): Promise;\n\tabstract _queryExec(sql: string, values: BasicSQLValue[]): Promise;\n\tabstract escapeId(param: string): string;\n\tquery(sql: SQLStatement): Promise;\n\tquery(): (strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise;\n\tquery(sql?: SQLStatement) {\n\t\tif (!sql) return (strings: any, ...rest: any) => this.query(new SQLStatement(strings, rest));\n\n\t\tconst [query, values] = this._resolveSQL(sql);\n\t\treturn this._query(query, values);\n\t}\n\tqueryOne(sql: SQLStatement): Promise;\n\tqueryOne(): (strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise;\n\tqueryOne(sql?: SQLStatement) {\n\t\tif (!sql) return (strings: any, ...rest: any) => this.queryOne(new SQLStatement(strings, rest));\n\n\t\treturn this.query(sql).then(res => Array.isArray(res) ? res[0] : res);\n\t}\n\tqueryExec(sql: SQLStatement): Promise;\n\tqueryExec(): (strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise;\n\tqueryExec(sql?: SQLStatement) {\n\t\tif (!sql) return (strings: any, ...rest: any) => this.queryExec(new SQLStatement(strings, rest));\n\n\t\tconst [query, values] = this._resolveSQL(sql);\n\t\treturn this._queryExec(query, values);\n\t}\n\tgetTable(name: string, primaryKeyName: keyof Row & string | null = null): DatabaseTable {\n\t\treturn new DatabaseTable(this, name, primaryKeyName);\n\t}\n\tclose() {\n\t\tvoid this.connection.end();\n\t}\n}\n\ntype PartialOrSQL = {\n\t[P in keyof T]?: T[P] | SQLStatement;\n};\n\ntype OkPacketOf = DB extends Database ? T : never;\n\n// Row extends SQLRow but TS doesn't support closed types so we can't express this\nexport class DatabaseTable {\n\tdb: DB;\n\tname: string;\n\tprimaryKeyName: keyof Row & string | null;\n\tconstructor(\n\t\tdb: DB,\n\t\tname: string,\n\t\tprimaryKeyName: keyof Row & string | null = null\n\t) {\n\t\tthis.db = db;\n\t\tthis.name = db.prefix + name;\n\t\tthis.primaryKeyName = primaryKeyName;\n\t}\n\tescapeId(param: string) {\n\t\treturn this.db.escapeId(param);\n\t}\n\n\t// raw\n\n\tquery(sql: SQLStatement): Promise;\n\tquery(): (strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise;\n\tquery(sql?: SQLStatement) {\n\t\treturn this.db.query(sql as any) as any;\n\t}\n\tqueryOne(sql: SQLStatement): Promise;\n\tqueryOne(): (strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise;\n\tqueryOne(sql?: SQLStatement) {\n\t\treturn this.db.queryOne(sql as any) as any;\n\t}\n\tqueryExec(sql: SQLStatement): Promise>;\n\tqueryExec(): (strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise>;\n\tqueryExec(sql?: SQLStatement) {\n\t\treturn this.db.queryExec(sql as any) as any;\n\t}\n\n\t// low-level\n\n\tselectAll(entries?: (keyof Row & string)[] | SQLStatement):\n\t(strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise {\n\t\tif (!entries) entries = SQL`*`;\n\t\tif (Array.isArray(entries)) entries = SQL`\"${entries}\"`;\n\t\treturn (strings, ...rest) =>\n\t\t\tthis.query()`SELECT ${entries} FROM \"${this.name}\" ${new SQLStatement(strings, rest)}`;\n\t}\n\tselectOne(entries?: (keyof Row & string)[] | SQLStatement):\n\t(strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise {\n\t\tif (!entries) entries = SQL`*`;\n\t\tif (Array.isArray(entries)) entries = SQL`\"${entries}\"`;\n\t\treturn (strings, ...rest) =>\n\t\t\tthis.queryOne()`SELECT ${entries} FROM \"${this.name}\" ${new SQLStatement(strings, rest)} LIMIT 1`;\n\t}\n\tupdateAll(partialRow: PartialOrSQL):\n\t(strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise> {\n\t\treturn (strings, ...rest) =>\n\t\t\tthis.queryExec()`UPDATE \"${this.name}\" SET ${partialRow as any} ${new SQLStatement(strings, rest)}`;\n\t}\n\tupdateOne(partialRow: PartialOrSQL):\n\t(strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise> {\n\t\treturn (s, ...r) =>\n\t\t\tthis.queryExec()`UPDATE \"${this.name}\" SET ${partialRow as any} ${new SQLStatement(s, r)} LIMIT 1`;\n\t}\n\tdeleteAll():\n\t(strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise> {\n\t\treturn (strings, ...rest) =>\n\t\t\tthis.queryExec()`DELETE FROM \"${this.name}\" ${new SQLStatement(strings, rest)}`;\n\t}\n\tdeleteOne():\n\t(strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise> {\n\t\treturn (strings, ...rest) =>\n\t\t\tthis.queryExec()`DELETE FROM \"${this.name}\" ${new SQLStatement(strings, rest)} LIMIT 1`;\n\t}\n\teval():\n\t(strings: TemplateStringsArray, ...rest: SQLValue[]) => Promise {\n\t\treturn (strings, ...rest) =>\n\t\t\tthis.queryOne<{ result: T }>(\n\t\t\t)`SELECT ${new SQLStatement(strings, rest)} AS result FROM \"${this.name}\" LIMIT 1`\n\t\t\t\t.then(row => row?.result);\n\t}\n\n\t// high-level\n\n\tinsert(partialRow: PartialOrSQL, where?: SQLStatement) {\n\t\treturn this.queryExec()`INSERT INTO \"${this.name}\" (${partialRow as SQLValue}) ${where}`;\n\t}\n\tinsertIgnore(partialRow: PartialOrSQL, where?: SQLStatement) {\n\t\treturn this.queryExec()`INSERT IGNORE INTO \"${this.name}\" (${partialRow as SQLValue}) ${where}`;\n\t}\n\tasync tryInsert(partialRow: PartialOrSQL, where?: SQLStatement) {\n\t\ttry {\n\t\t\treturn await this.insert(partialRow, where);\n\t\t} catch (err: any) {\n\t\t\tif (err.code === 'ER_DUP_ENTRY') {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\tupsert(partialRow: PartialOrSQL, partialUpdate = partialRow, where?: SQLStatement) {\n\t\tif (this.db.type === 'pg') {\n\t\t\treturn this.queryExec(\n\t\t\t)`INSERT INTO \"${this.name}\" (${partialRow as any}) ON CONFLICT (${this.primaryKeyName\n\t\t\t}) DO UPDATE ${partialUpdate as any} ${where}`;\n\t\t}\n\t\treturn this.queryExec(\n\t\t)`INSERT INTO \"${this.name}\" (${partialRow as any}) ON DUPLICATE KEY UPDATE ${partialUpdate as any} ${where}`;\n\t}\n\tset(primaryKey: BasicSQLValue, partialRow: PartialOrSQL, where?: SQLStatement) {\n\t\tif (!this.primaryKeyName) throw new Error(`Cannot set() without a single-column primary key`);\n\t\tpartialRow[this.primaryKeyName] = primaryKey as any;\n\t\treturn this.replace(partialRow, where);\n\t}\n\treplace(partialRow: PartialOrSQL, where?: SQLStatement) {\n\t\treturn this.queryExec()`REPLACE INTO \"${this.name}\" (${partialRow as SQLValue}) ${where}`;\n\t}\n\tget(primaryKey: BasicSQLValue, entries?: (keyof Row & string)[] | SQLStatement) {\n\t\tif (!this.primaryKeyName) throw new Error(`Cannot get() without a single-column primary key`);\n\t\treturn this.selectOne(entries)`WHERE \"${this.primaryKeyName}\" = ${primaryKey}`;\n\t}\n\tdelete(primaryKey: BasicSQLValue) {\n\t\tif (!this.primaryKeyName) throw new Error(`Cannot delete() without a single-column primary key`);\n\t\treturn this.deleteAll()`WHERE \"${this.primaryKeyName}\" = ${primaryKey} LIMIT 1`;\n\t}\n\tupdate(primaryKey: BasicSQLValue, data: PartialOrSQL) {\n\t\tif (!this.primaryKeyName) throw new Error(`Cannot update() without a single-column primary key`);\n\t\treturn this.updateAll(data)`WHERE \"${this.primaryKeyName}\" = ${primaryKey} LIMIT 1`;\n\t}\n}\n\nexport class MySQLDatabase extends Database {\n\toverride type = 'mysql' as const;\n\tconstructor(config: mysql.PoolOptions & { prefix?: string }) {\n\t\tconst prefix = config.prefix || \"\";\n\t\tif (config.prefix) {\n\t\t\tconfig = { ...config };\n\t\t\tdelete config.prefix;\n\t\t}\n\t\tsuper(mysql.createPool(config), prefix);\n\t}\n\toverride _resolveSQL(query: SQLStatement): [query: string, values: BasicSQLValue[]] {\n\t\tlet sql = query.sql[0];\n\t\tconst values = [];\n\t\tfor (let i = 0; i < query.values.length; i++) {\n\t\t\tconst value = query.values[i];\n\t\t\tif (query.sql[i + 1].startsWith('`') || query.sql[i + 1].startsWith('\"')) {\n\t\t\t\tsql = sql.slice(0, -1) + this.escapeId(`${value}`) + query.sql[i + 1].slice(1);\n\t\t\t} else {\n\t\t\t\tsql += '?' + query.sql[i + 1];\n\t\t\t\tvalues.push(value);\n\t\t\t}\n\t\t}\n\t\treturn [sql, values];\n\t}\n\toverride _query(query: string, values: BasicSQLValue[]): Promise {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.connection.query(query, values, (e, results: any) => {\n\t\t\t\tif (e) {\n\t\t\t\t\treturn reject(new Error(`${e.message} (${query}) (${values}) [${e.code}]`));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(results)) {\n\t\t\t\t\tfor (const row of results) {\n\t\t\t\t\t\tfor (const col in row) {\n\t\t\t\t\t\t\tif (Buffer.isBuffer(row[col])) row[col] = row[col].toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn resolve(results);\n\t\t\t});\n\t\t});\n\t}\n\toverride _queryExec(sql: string, values: BasicSQLValue[]): Promise {\n\t\treturn this._query(sql, values);\n\t}\n\toverride escapeId(id: string) {\n\t\treturn mysql.escapeId(id);\n\t}\n}\n\nexport class PGDatabase extends Database {\n\toverride type = 'pg' as const;\n\tconstructor(config: pg.PoolConfig) {\n\t\tsuper(new pg.Pool(config));\n\t}\n\toverride _resolveSQL(query: SQLStatement): [query: string, values: BasicSQLValue[]] {\n\t\tlet sql = query.sql[0];\n\t\tconst values = [];\n\t\tlet paramCount = 0;\n\t\tfor (let i = 0; i < query.values.length; i++) {\n\t\t\tconst value = query.values[i];\n\t\t\tif (query.sql[i + 1].startsWith('`') || query.sql[i + 1].startsWith('\"')) {\n\t\t\t\tsql = sql.slice(0, -1) + this.escapeId(`${value}`) + query.sql[i + 1].slice(1);\n\t\t\t} else {\n\t\t\t\tparamCount++;\n\t\t\t\tsql += `$${paramCount}` + query.sql[i + 1];\n\t\t\t\tvalues.push(value);\n\t\t\t}\n\t\t}\n\t\treturn [sql, values];\n\t}\n\toverride _query(query: string, values: BasicSQLValue[]) {\n\t\treturn this.connection.query(query, values).then(res => res.rows);\n\t}\n\toverride _queryExec(query: string, values: BasicSQLValue[]) {\n\t\treturn this.connection.query(query, values).then(res => ({ affectedRows: res.rowCount }));\n\t}\n\toverride escapeId(id: string) {\n\t\t// @ts-expect-error @types/pg really needs to be updated\n\t\treturn pg.escapeIdentifier(id);\n\t}\n}\n"], "mappings": "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", "names": [] }