diff --git a/db/DatabaseConnection.ts b/db/DatabaseConnection.ts index 10d19f0e9a3..a2e17556fda 100644 --- a/db/DatabaseConnection.ts +++ b/db/DatabaseConnection.ts @@ -1,8 +1,8 @@ -import mysql from "mysql" +import mysql2 from "mysql2" class TransactionContext { - conn: mysql.PoolConnection - constructor(conn: mysql.PoolConnection) { + conn: mysql2.PoolConnection + constructor(conn: mysql2.PoolConnection) { this.conn = conn } @@ -27,19 +27,19 @@ class TransactionContext { // Promise wrapper for node-mysql with transaction support and some shorthands export class DatabaseConnection { - config: mysql.PoolConfig - pool!: mysql.Pool + config: mysql2.PoolOptions + pool!: mysql2.Pool - constructor(config: mysql.PoolConfig) { + constructor(config: mysql2.PoolOptions) { this.config = config } async connect(): Promise { - this.pool = mysql.createPool(this.config) + this.pool = mysql2.createPool(this.config) await this.getConnection() } - getConnection(): Promise { + getConnection(): Promise { return new Promise((resolve, reject) => { this.pool.getConnection((poolerr, conn) => { if (poolerr) { diff --git a/db/db.ts b/db/db.ts index abca1728962..b3dd0ed7d50 100644 --- a/db/db.ts +++ b/db/db.ts @@ -35,7 +35,7 @@ export const knexInstance = (): Knex => { if (_knexInstance) return _knexInstance _knexInstance = knex({ - client: "mysql", + client: "mysql2", connection: { host: GRAPHER_DB_HOST, user: GRAPHER_DB_USER, @@ -47,6 +47,12 @@ export const knexInstance = (): Knex => { if (field.type === "TINY" && field.length === 1) { return field.string() === "1" // 1 = true, 0 = false } + + // mysql2 driver will return JSON objects, which is nice, but we have many code paths that expect JSON strings + // so we convert JSON objects to JSON strings here (for now) + if (field.type === "JSON") { + return field.string("utf8") + } return next() }, }, diff --git a/db/model/Variable.ts b/db/model/Variable.ts index 5ebb8ddab73..9d7d8c8eb70 100644 --- a/db/model/Variable.ts +++ b/db/model/Variable.ts @@ -8,7 +8,7 @@ import { } from "@ourworldindata/grapher" import pl from "nodejs-polars" import { DATA_API_URL } from "../../settings/serverSettings.js" -import { escape } from "mysql" +import { escape } from "mysql2" import { OwidChartDimensionInterface, OwidVariableDisplayConfigInterface, diff --git a/db/sql-ts/sql-ts-config.json b/db/sql-ts/sql-ts-config.json index 5114f758d96..3a645e536d1 100644 --- a/db/sql-ts/sql-ts-config.json +++ b/db/sql-ts/sql-ts-config.json @@ -1,5 +1,5 @@ { - "client": "mysql", + "client": "mysql2", "connection": { "host": "localhost", "user": "grapher", diff --git a/db/tests/dbTestConfig.ts b/db/tests/dbTestConfig.ts index 08af28f0a5c..3fe1539f05a 100644 --- a/db/tests/dbTestConfig.ts +++ b/db/tests/dbTestConfig.ts @@ -9,7 +9,7 @@ import { } from "../../settings/serverSettings.js" export const dbTestConfig = { - client: "mysql", + client: "mysql2", connection: { database: GRAPHER_TEST_DB_NAME, user: GRAPHER_TEST_DB_USER, diff --git a/knexfile.ts b/knexfile.ts index c2c2fc5b3d3..cdd237a7ef5 100644 --- a/knexfile.ts +++ b/knexfile.ts @@ -9,7 +9,7 @@ import { } from "../settings/serverSettings.js" const dbConfig = { - client: "mysql", + client: "mysql2", connection: { database: GRAPHER_DB_NAME, user: GRAPHER_DB_USER, diff --git a/package.json b/package.json index 3dc1f7cd4cd..a7e8b1a00c8 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,6 @@ "@types/mdast": "^3.0", "@types/minimist": "^1.2.2", "@types/mousetrap": "^1.6.9", - "@types/mysql": "^2.15.21", "@types/papaparse": "^5.3.5", "@types/progress": "^2.0.5", "@types/randomstring": "^1.1.8", @@ -161,7 +160,7 @@ "mobx-react": "5", "mobx-utils": "5", "mousetrap": "^1.6.5", - "mysql": "^2.18.1", + "mysql2": "^3.9.7", "nodejs-polars": "^0.7.2", "normalize.css": "^8.0.1", "openai": "^4.6.0", diff --git a/yarn.lock b/yarn.lock index d22b4248fab..877bf388dda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5127,15 +5127,6 @@ __metadata: languageName: node linkType: hard -"@types/mysql@npm:^2.15.21": - version: 2.15.21 - resolution: "@types/mysql@npm:2.15.21" - dependencies: - "@types/node": "npm:*" - checksum: 10/79fe91e1242d78b8aae15d883347f5a4f330452855c112fe465aef570e696def33dd8fea163e00416629eddc20b3a075e6146826881f813a0e1b52e47f39159a - languageName: node - linkType: hard - "@types/node-fetch@npm:^2.6.4": version: 2.6.4 resolution: "@types/node-fetch@npm:2.6.4" @@ -6624,13 +6615,6 @@ __metadata: languageName: node linkType: hard -"bignumber.js@npm:9.0.0": - version: 9.0.0 - resolution: "bignumber.js@npm:9.0.0" - checksum: 10/7406d0d11dfdd2183e19be745f0d5913e3773ded5fbca2a310221e719f15fd8ec6b8d7991031a6081a6276a8e12e27d58ead60f73dcbb9d697ebe9e2dd0ad7e0 - languageName: node - linkType: hard - "bignumber.js@npm:^8.0.1": version: 8.1.1 resolution: "bignumber.js@npm:8.1.1" @@ -8640,6 +8624,13 @@ __metadata: languageName: node linkType: hard +"denque@npm:^2.1.0": + version: 2.1.0 + resolution: "denque@npm:2.1.0" + checksum: 10/8ea05321576624b90acfc1ee9208b8d1d04b425cf7573b9b4fa40a2c3ed4d4b0af5190567858f532f677ed2003d4d2b73c8130b34e3c7b8d5e88cdcfbfaa1fe7 + languageName: node + linkType: hard + "depd@npm:2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" @@ -10552,6 +10543,15 @@ __metadata: languageName: node linkType: hard +"generate-function@npm:^2.3.1": + version: 2.3.1 + resolution: "generate-function@npm:2.3.1" + dependencies: + is-property: "npm:^1.0.2" + checksum: 10/318f85af87c3258d86df4ebbb56b63a2ae52e71bd6cde8d0a79de09450de7422a7047fb1f8d52ccc135564a36cb986d73c63149eed96b7ac57e38acba44f29e2 + languageName: node + linkType: hard + "gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" @@ -11056,7 +11056,6 @@ __metadata: "@types/mdast": "npm:^3.0" "@types/minimist": "npm:^1.2.2" "@types/mousetrap": "npm:^1.6.9" - "@types/mysql": "npm:^2.15.21" "@types/papaparse": "npm:^5.3.5" "@types/progress": "npm:^2.0.5" "@types/randomstring": "npm:^1.1.8" @@ -11144,7 +11143,7 @@ __metadata: mobx-react: "npm:5" mobx-utils: "npm:5" mousetrap: "npm:^1.6.5" - mysql: "npm:^2.18.1" + mysql2: "npm:^3.9.7" nodejs-polars: "npm:^0.7.2" normalize.css: "npm:^8.0.1" openai: "npm:^4.6.0" @@ -11662,7 +11661,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -12266,6 +12265,13 @@ __metadata: languageName: node linkType: hard +"is-property@npm:^1.0.2": + version: 1.0.2 + resolution: "is-property@npm:1.0.2" + checksum: 10/2f66eacb3d7237ba5c725496672edec656a20b12c80790921988578e6b11c258a062ce1e602f3cd2e3c2e05dd8b6e24e1d59254375207f157424a02ef0abb3d7 + languageName: node + linkType: hard + "is-regex@npm:^1.0.5, is-regex@npm:^1.1.4": version: 1.1.4 resolution: "is-regex@npm:1.1.4" @@ -13807,6 +13813,13 @@ __metadata: languageName: node linkType: hard +"long@npm:^5.2.1": + version: 5.2.3 + resolution: "long@npm:5.2.3" + checksum: 10/9167ec6947a825b827c30da169a7384eec6c0c9ec2f0b9c74da2e93d81159bbe39fb09c3f13dae9721d4b807ccfa09797a7dd1012f5d478e3e33ca3c78b608e6 + languageName: node + linkType: hard + "loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" @@ -13843,10 +13856,17 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^7.4.4, lru-cache@npm:^7.5.1, lru-cache@npm:^7.7.1": - version: 7.14.0 - resolution: "lru-cache@npm:7.14.0" - checksum: 10/f8e01009712d19e9da6001a9639188dc9a98f2686ed437a31432792c676e45a3ced8c4d28b117c18fd45eb49c7f8e676e5a5c31bf59c46a8ca0971c6b5280bc2 +"lru-cache@npm:^7.14.1, lru-cache@npm:^7.4.4, lru-cache@npm:^7.5.1, lru-cache@npm:^7.7.1": + version: 7.18.3 + resolution: "lru-cache@npm:7.18.3" + checksum: 10/6029ca5aba3aacb554e919d7ef804fffd4adfc4c83db00fac8248c7c78811fb6d4b6f70f7fd9d55032b3823446546a007edaa66ad1f2377ae833bd983fac5d98 + languageName: node + linkType: hard + +"lru-cache@npm:^8.0.0": + version: 8.0.5 + resolution: "lru-cache@npm:8.0.5" + checksum: 10/74153ab136d0c2d735003b8b1c0fa8213c94c2520701dfe8bb31d957f975b3d3665b1ef27ac9a5b9f92c8f581c79008834c0f9bd60c5adf368476f9a95e8fa82 languageName: node linkType: hard @@ -14600,15 +14620,19 @@ __metadata: languageName: node linkType: hard -"mysql@npm:^2.18.1": - version: 2.18.1 - resolution: "mysql@npm:2.18.1" +"mysql2@npm:^3.9.7": + version: 3.9.7 + resolution: "mysql2@npm:3.9.7" dependencies: - bignumber.js: "npm:9.0.0" - readable-stream: "npm:2.3.7" - safe-buffer: "npm:5.1.2" - sqlstring: "npm:2.3.1" - checksum: 10/87d80e374717d7767d3e609f7f5e09987fa4dee208ba346ff269fffd2500719dcf2f65ac86c8e77649c3d52b86811a88e33cfd06e7e4a48cec53ecd4ac85c08d + denque: "npm:^2.1.0" + generate-function: "npm:^2.3.1" + iconv-lite: "npm:^0.6.3" + long: "npm:^5.2.1" + lru-cache: "npm:^8.0.0" + named-placeholders: "npm:^1.1.3" + seq-queue: "npm:^0.0.5" + sqlstring: "npm:^2.3.2" + checksum: 10/7f43b17cc0acdec30791c9b29a97c75f7e4512bbf41c2baa383ce76b50d0a92300083a8dba3cc019423ee3b7710ed7c756baf805449f0c9650e08e5d48454b07 languageName: node linkType: hard @@ -14623,6 +14647,15 @@ __metadata: languageName: node linkType: hard +"named-placeholders@npm:^1.1.3": + version: 1.1.3 + resolution: "named-placeholders@npm:1.1.3" + dependencies: + lru-cache: "npm:^7.14.1" + checksum: 10/7834adc91e92ae1b9c4413384e3ccd297de5168bb44017ff0536705ddc4db421723bd964607849265feb3f6ded390f84cf138e5925f22f7c13324f87a803dc73 + languageName: node + linkType: hard + "nanoid@npm:^3.3.3, nanoid@npm:^3.3.6": version: 3.3.7 resolution: "nanoid@npm:3.3.7" @@ -17399,7 +17432,18 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:2.3.7, readable-stream@npm:~2.3.6": +"readable-stream@npm:^3.0.0, readable-stream@npm:^3.0.2, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": + version: 3.6.0 + resolution: "readable-stream@npm:3.6.0" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: 10/b80b3e6a7fafb1c79de7db541de357f4a5ee73bd70c21672f5a7c840d27bb27bdb0151e7ba2fd82c4a888df22ce0c501b0d9f3e4dfe51688876701c437d59536 + languageName: node + linkType: hard + +"readable-stream@npm:~2.3.6": version: 2.3.7 resolution: "readable-stream@npm:2.3.7" dependencies: @@ -17414,17 +17458,6 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.0.0, readable-stream@npm:^3.0.2, readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": - version: 3.6.0 - resolution: "readable-stream@npm:3.6.0" - dependencies: - inherits: "npm:^2.0.3" - string_decoder: "npm:^1.1.1" - util-deprecate: "npm:^1.0.1" - checksum: 10/b80b3e6a7fafb1c79de7db541de357f4a5ee73bd70c21672f5a7c840d27bb27bdb0151e7ba2fd82c4a888df22ce0c501b0d9f3e4dfe51688876701c437d59536 - languageName: node - linkType: hard - "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -18057,6 +18090,13 @@ __metadata: languageName: node linkType: hard +"seq-queue@npm:^0.0.5": + version: 0.0.5 + resolution: "seq-queue@npm:0.0.5" + checksum: 10/fa302e3b2aaece644532603ae42d675f9b8750e395a98740dd58dc5e02985ce6f0c2b78715b5984d6f6a807893735a14212a70d6ec591e6fba410397269588a0 + languageName: node + linkType: hard + "serve-static@npm:1.15.0": version: 1.15.0 resolution: "serve-static@npm:1.15.0" @@ -18509,14 +18549,7 @@ __metadata: languageName: node linkType: hard -"sqlstring@npm:2.3.1": - version: 2.3.1 - resolution: "sqlstring@npm:2.3.1" - checksum: 10/bc09237002da7e1172098e7d47401ea0ae45c1e4b224619f7ee2905dc921321f5ccc8c5e076994890df01b4a3363b2b5ea295b7a10d32a35181ef25bad158093 - languageName: node - linkType: hard - -"sqlstring@npm:^2.3.3": +"sqlstring@npm:^2.3.2, sqlstring@npm:^2.3.3": version: 2.3.3 resolution: "sqlstring@npm:2.3.3" checksum: 10/4e5a25af2d77a031fe00694034bf9fd822ddc3a483c9383124b120aa6b9ae9ab71e173cd29fba9c653998ebfef9e97be668957839960b9b3dc1afcb45f1ddb64