Skip to content

Commit

Permalink
Fix: Knex cannot set a default value for TEXT field (MariaDB) (#5261)
Browse files Browse the repository at this point in the history
  • Loading branch information
louislam authored Oct 28, 2024
1 parent 277d6fe commit ca09429
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 25 deletions.
62 changes: 39 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@
"jsonwebtoken": "~9.0.0",
"jwt-decode": "~3.1.2",
"kafkajs": "^2.2.4",
"knex": "^2.4.2",
"knex": "~3.1.0",
"limiter": "~2.1.0",
"liquidjs": "^10.7.0",
"marked": "^14.0.0",
"mitt": "~3.0.1",
"mongodb": "~4.17.1",
"mqtt": "~4.3.7",
"mssql": "~11.0.0",
"mysql2": "~3.9.6",
"mysql2": "~3.11.3",
"nanoid": "~3.3.4",
"net-snmp": "^3.11.2",
"node-cloudflared-tunnel": "~1.0.9",
Expand Down
9 changes: 9 additions & 0 deletions server/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { Settings } = require("./settings");
const { UptimeCalculator } = require("./uptime-calculator");
const dayjs = require("dayjs");
const { SimpleMigrationServer } = require("./utils/simple-migration-server");
const KumaColumnCompiler = require("./utils/knex/lib/dialects/mysql2/schema/mysql2-columncompiler");

/**
* Database & App Data Folder
Expand Down Expand Up @@ -198,6 +199,14 @@ class Database {
* @returns {Promise<void>}
*/
static async connect(testMode = false, autoloadModels = true, noLog = false) {
// Patch "mysql2" knex client
// Workaround: Tried extending the ColumnCompiler class, but it didn't work for unknown reasons, so I override the function via prototype
const { getDialectByNameOrAlias } = require("knex/lib/dialects");
const mysql2 = getDialectByNameOrAlias("mysql2");
mysql2.prototype.columnCompiler = function () {
return new KumaColumnCompiler(this, ...arguments);
};

const acquireConnectionTimeout = 120 * 1000;
let dbConfig;
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const ColumnCompilerMySQL = require("knex/lib/dialects/mysql/schema/mysql-columncompiler");
const { formatDefault } = require("knex/lib/formatter/formatterUtils");
const { log } = require("../../../../../../../src/util");

class KumaColumnCompiler extends ColumnCompilerMySQL {
/**
* Override defaultTo method to handle default value for TEXT fields
* @param {any} value Value
* @returns {string|void} Default value (Don't understand why it can return void or string, but it's the original code, lol)
*/
defaultTo(value) {
if (this.type === "text" && typeof value === "string") {
log.debug("defaultTo", `${this.args[0]}: ${this.type} ${value} ${typeof value}`);
// MySQL 8.0 is required and only if the value is written as an expression: https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html
// MariaDB 10.2 is required: https://mariadb.com/kb/en/text/
return `default (${formatDefault(value, this.type, this.client)})`;
}
return super.defaultTo.apply(this, arguments);
}
}

module.exports = KumaColumnCompiler;

0 comments on commit ca09429

Please sign in to comment.