feat: plugin text columns are longtext on mysql so they are not capped at 64KB

This commit is contained in:
LukeGus committed 2026-10-09 09:39:08 -05:00
1 parent 83cce344e8
commit 0ce378ec55
4 files changed
+10 -7

No files matched your search

+1
View File
@@ -7,6 +7,7 @@
- `execCommand` timeout errors no longer include the command, which could hold a sudo password
- `termix-plugin validate` fails when a plugin ships migrations for some database engines but not all three
- `termix-plugin migrations` loads the table definitions from a path with a `#` or other URL characters in it
- Text, json and encrypted columns are `longtext` on MySQL in new migrations, so they are no longer capped at 64KB. Existing migrations keep `text`
- `i18next`, `react-dom`, `react-i18next` and `sonner` are optional peer dependencies, so npm stops installing them into backend-only plugins
## 1.0.4
+1 -1
View File
@@ -69,7 +69,7 @@ function builder(column: PluginColumn): Builder {
export const id = () =>
builder({ type: "id", primaryKey: true, notNull: true });
/** Unbounded string. Never indexable: MySQL cannot index TEXT. */
/** Unbounded string, LONGTEXT on MySQL. Never indexable: MySQL cannot index TEXT. */
export const text = () => builder({ type: "text" });
/** Bounded string. Indexable on every engine. */
+3 -1
View File
@@ -80,11 +80,13 @@ function columnType(
// though it was declared unbounded. defineTable refuses to index a
// text/json column, so in practice this only catches a primary key.
if (keyed && dialect !== "sqlite") return `varchar(${KEY_LENGTH})`;
// MySQL TEXT stops at 64KB, so free text, json and secrets go long.
if (dialect === "mysql" && column.type !== "timestamp") return "longtext";
return "text";
}
}
/** Column types that are TEXT on MySQL when nothing keys them. */
/** Column types that are TEXT or LONGTEXT on MySQL when nothing keys them. */
const TEXT_ON_MYSQL: ReadonlySet<PluginColumn["type"]> = new Set([
"text",
"json",
+5 -5
View File
@@ -184,9 +184,9 @@ describe("createTableSql", () => {
\`user_id\` varchar(255) NOT NULL,
\`host_id\` int NOT NULL,
\`title\` varchar(200) NOT NULL,
\`body\` text,
\`meta\` text,
\`secret\` text,
\`body\` longtext,
\`meta\` longtext,
\`secret\` longtext,
\`pinned\` boolean DEFAULT false,
\`position\` int DEFAULT 0,
\`size\` bigint,
@@ -286,9 +286,9 @@ describe("adoptTableSql", () => {
expect(mysql[1]).toBe("RENAME TABLE `fleets` TO `p_fleets_fleets`;");
});
it("writes a TEXT default as an expression on MySQL", () => {
it("writes a long text default as an expression on MySQL", () => {
expect(adoptTableSql("mysql", "fleets", adopted)[0]).toContain(
"`name` text NOT NULL DEFAULT ('x')",
"`name` longtext NOT NULL DEFAULT ('x')",
);
expect(createTableSql("sqlite", "fleets", adopted)[0]).toContain(
"\"name\" text NOT NULL DEFAULT 'x'",