From 0e49b09d38f0f91bffbadf96184c4c37fd71b779 Mon Sep 17 00:00:00 2001 From: Rory& Date: Fri, 20 Mar 2026 15:23:12 +0100 Subject: [PATCH] Remove all traces of sqlite3 - resolves #1617 --- .github/workflows/build.yml | 56 ++++++++++++++++++------------------ package.json | 1 + src/bundle/start.ts | 8 ++---- src/util/entities/Channel.ts | 3 ++ src/util/entities/Guild.ts | 2 +- src/util/util/Database.ts | 50 +++++++++----------------------- 6 files changed, 48 insertions(+), 72 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4eff6e5e7..26787bc5a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,28 +1,28 @@ -name: Build - -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - -jobs: - build: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [24.x] - # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ - - steps: - - uses: actions/checkout@v5 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v5 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm ci - - run: npm install --no-save sqlite3 --force - - run: npm run build --if-present - - run: npm run test --if-present +#name: Build +# +#on: +# push: +# branches: [ "master" ] +# pull_request: +# branches: [ "master" ] +# +#jobs: +# build: +# runs-on: ubuntu-latest +# +# strategy: +# matrix: +# node-version: [24.x] +# # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ +# +# steps: +# - uses: actions/checkout@v5 +# - name: Use Node.js ${{ matrix.node-version }} +# uses: actions/setup-node@v5 +# with: +# node-version: ${{ matrix.node-version }} +# cache: 'npm' +# - run: npm ci +# - run: npm install --no-save sqlite3 --force +# - run: npm run build --if-present +# - run: npm run test --if-present diff --git a/package.json b/package.json index 53b1cdb48..d52a7c45a 100644 --- a/package.json +++ b/package.json @@ -139,6 +139,7 @@ }, "overrides": { "typeorm": { + "better-sqlite3": "../_EXCLUDED_", "sqlite3": "../_EXCLUDED_", "mongodb": "../_EXCLUDED_" } diff --git a/src/bundle/start.ts b/src/bundle/start.ts index 254241f67..54be11297 100644 --- a/src/bundle/start.ts +++ b/src/bundle/start.ts @@ -64,12 +64,8 @@ if (cluster.isPrimary) { // Fork workers. for (let i = 0; i < cores; i++) { - // Delay each worker start if using sqlite database to prevent locking it - const delay = process.env.DATABASE?.includes("://") ? 0 : i * 1000; - setTimeout(() => { - cluster.fork(); - console.log(`[Process] Worker ${cyan(i)} started.`); - }, delay); + cluster.fork(); + console.log(`[Process] Worker ${cyan(i)} started.`); } cluster.on("message", (sender: Worker, message) => { diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts index 9c7ddb571..c924a582d 100644 --- a/src/util/entities/Channel.ts +++ b/src/util/entities/Channel.ts @@ -183,6 +183,9 @@ export class Channel extends BaseClass { @Column("text", { array: true, nullable: true }) applied_tags?: string[]; + @Column("text", { nullable: true }) + status?: string | null; + /** Must be calculated Channel.calculatePosition */ position: number; diff --git a/src/util/entities/Guild.ts b/src/util/entities/Guild.ts index 29d4de584..2a11594af 100644 --- a/src/util/entities/Guild.ts +++ b/src/util/entities/Guild.ts @@ -383,7 +383,7 @@ export class Guild extends BaseClass { region: Config.get().regions.default, }).save(); - // we have to create the role _after_ the guild because else we would get a "SQLITE_CONSTRAINT: FOREIGN KEY constraint failed" error + // we have to create the role _after_ the guild because else we would get a foreign key error // TODO: make the @everyone a pseudorole that is dynamically generated at runtime so we can save storage await Role.create({ id: guild_id, diff --git a/src/util/util/Database.ts b/src/util/util/Database.ts index 8f4119a16..745db5ef4 100644 --- a/src/util/util/Database.ts +++ b/src/util/util/Database.ts @@ -37,35 +37,19 @@ if (!process.env) { } if (process.argv[1]?.endsWith("scripts/openapi.js")) isHeadlessProcess = true; -const dbConnectionString = process.env.DATABASE || path.join(process.cwd(), "database.db"); - -export const DatabaseType = dbConnectionString.includes("://") ? dbConnectionString.split(":")[0]?.replace("+srv", "") : "sqlite"; -const isSqlite = DatabaseType.includes("sqlite"); -const applyMigrations = process.env.APPLY_DB_MIGRATIONS !== "false"; - -// For openapi.js... -if (!isHeadlessProcess) { - let hasWarnedSqlite = false; - if (isSqlite && !hasWarnedSqlite) { - hasWarnedSqlite = true; - console.log( - `[Database] ${red(`You do not have a database configured. This implies that it will try to use SQLite, which has been broken for a while and is unlikely to see a real fix any time soon.`)}`, - ); - console.log(`[Database] ${red(`Please set up a PostgreSQL database instead: https://docs.spacebar.chat/setup/server/database/.`)}`); - console.log( - `[Database] ${red(`Alternatively, if you're able to install Nix (except MacOSX), and are trying to run a quick and dirty localhost instance: nix run .\\#testVm.config.system.build.vm, then open a client and connect to http://localhost:8080`)}`, - ); - console.log(`[Database] ${red(`If you would like to try *anyways*, see the error below:`)}`); - try { - // TODO: fully remove sqlite3 - require("sqlite3"); - } catch (e) { - console.log(`[Database] ${red(`Failed to load sqlite3 package. Please install it with 'npm install --no-save sqlite3', or switch to a real database like Postgres.`)}`); - process.exit(1); - } - } +if (!process.env.DATABASE) { + console.log( + red( + "DATABASE environment variable not set! Please set it to your database connection string.\n" + "Example for postgres: postgres://user:password@localhost:5432/database", + ), + ); + process.exit(1); } +const dbConnectionString = process.env.DATABASE!; +export const DatabaseType = dbConnectionString.split(":")[0]?.replace("+srv", ""); +const applyMigrations = process.env.APPLY_DB_MIGRATIONS !== "false"; + export const DataSourceOptions = isHeadlessProcess ? (undefined as unknown as DataSource) : new DataSource({ @@ -73,8 +57,7 @@ export const DataSourceOptions = isHeadlessProcess //@ts-ignore type 'string' is not 'sqlite' | 'postgres' | etc etc type: DatabaseType, charset: "utf8mb4", - url: isSqlite ? undefined : dbConnectionString, - database: isSqlite ? dbConnectionString : undefined, + url: process.env.DATABASE, entities: [path.join(__dirname, "..", "entities", "*.js")], synchronize: !!process.env.DB_SYNC, logging: !!process.env.DB_LOGGING, @@ -96,7 +79,7 @@ export async function initDatabase(): Promise { if (dbConnection) return dbConnection; if (!process.env.DB_SYNC) { - const supported = ["postgres", "sqlite"]; + const supported = ["postgres"]; if (!supported.includes(DatabaseType)) { console.log( "[Database]" + @@ -113,13 +96,6 @@ export async function initDatabase(): Promise { dbConnection = await DataSourceOptions.initialize(); - if (DatabaseType === "sqlite") { - console.log(`[Database] ${yellow("Warning: SQLite is not supported. Forcing sync, this may lead to data loss!")}`); - await dbConnection.synchronize(); - console.log(`[Database] ${green("Connected")}`); - return dbConnection; - } - // Crude way of detecting if the migrations table exists. const dbExists = async () => { try {