diff --git a/package.json b/package.json index 5ef0ecdb..dae9d098 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "lint": "eslint \"**/*.{js,jsx,ts,tsx,json,md}\"", "lint-fix": "yarn lint --fix", "quick": "pretty-quick --staged", - "postinstall": "husky install" + "postinstall": "husky install", + "migration:create": "yarn typeorm migration:create" }, "lint-staged": { "*.{js,jsx,ts,tsx,json,md}": "eslint --fix" diff --git a/packages/server/src/DataSource.ts b/packages/server/src/DataSource.ts index b0d56477..9265e55f 100644 --- a/packages/server/src/DataSource.ts +++ b/packages/server/src/DataSource.ts @@ -1,26 +1,26 @@ import 'reflect-metadata' import path from 'path' import { DataSource } from 'typeorm' -import { ChatFlow } from './entity/ChatFlow' -import { ChatMessage } from './entity/ChatMessage' -import { Credential } from './entity/Credential' -import { Tool } from './entity/Tool' import { getUserHome } from './utils' +import { entities } from './database/entities' +import { sqliteMigrations } from './database/migrations/sqlite' +import { mysqlMigrations } from './database/migrations/mysql' +import { postgresMigrations } from './database/migrations/postgres' let appDataSource: DataSource export const init = async (): Promise => { let homePath - const synchronize = process.env.OVERRIDE_DATABASE === 'false' ? false : true switch (process.env.DATABASE_TYPE) { case 'sqlite': homePath = process.env.DATABASE_PATH ?? path.join(getUserHome(), '.flowise') appDataSource = new DataSource({ type: 'sqlite', database: path.resolve(homePath, 'database.sqlite'), - synchronize, - entities: [ChatFlow, ChatMessage, Tool, Credential], - migrations: [] + synchronize: false, + migrationsRun: false, + entities: Object.values(entities), + migrations: sqliteMigrations }) break case 'mysql': @@ -32,9 +32,10 @@ export const init = async (): Promise => { password: process.env.DATABASE_PASSWORD, database: process.env.DATABASE_NAME, charset: 'utf8mb4', - synchronize, - entities: [ChatFlow, ChatMessage, Tool, Credential], - migrations: [] + synchronize: false, + migrationsRun: false, + entities: Object.values(entities), + migrations: mysqlMigrations }) break case 'postgres': @@ -45,9 +46,10 @@ export const init = async (): Promise => { username: process.env.DATABASE_USER, password: process.env.DATABASE_PASSWORD, database: process.env.DATABASE_NAME, - synchronize, - entities: [ChatFlow, ChatMessage, Tool, Credential], - migrations: [] + synchronize: false, + migrationsRun: false, + entities: Object.values(entities), + migrations: postgresMigrations }) break default: @@ -55,9 +57,10 @@ export const init = async (): Promise => { appDataSource = new DataSource({ type: 'sqlite', database: path.resolve(homePath, 'database.sqlite'), - synchronize, - entities: [ChatFlow, ChatMessage, Tool, Credential], - migrations: [] + synchronize: false, + migrationsRun: false, + entities: Object.values(entities), + migrations: sqliteMigrations }) break } diff --git a/packages/server/src/entity/ChatFlow.ts b/packages/server/src/database/entities/ChatFlow.ts similarity index 87% rename from packages/server/src/entity/ChatFlow.ts rename to packages/server/src/database/entities/ChatFlow.ts index 4c37e083..a4fdd130 100644 --- a/packages/server/src/entity/ChatFlow.ts +++ b/packages/server/src/database/entities/ChatFlow.ts @@ -1,6 +1,6 @@ /* eslint-disable */ import { Entity, Column, CreateDateColumn, UpdateDateColumn, PrimaryGeneratedColumn } from 'typeorm' -import { IChatFlow } from '../Interface' +import { IChatFlow } from '../../Interface' @Entity() export class ChatFlow implements IChatFlow { @@ -22,7 +22,7 @@ export class ChatFlow implements IChatFlow { @Column({ nullable: true }) apikeyid?: string - @Column({ nullable: true }) + @Column({ nullable: true, type: 'text' }) chatbotConfig?: string @CreateDateColumn() diff --git a/packages/server/src/entity/ChatMessage.ts b/packages/server/src/database/entities/ChatMessage.ts similarity index 80% rename from packages/server/src/entity/ChatMessage.ts rename to packages/server/src/database/entities/ChatMessage.ts index 8123020c..4b5306ee 100644 --- a/packages/server/src/entity/ChatMessage.ts +++ b/packages/server/src/database/entities/ChatMessage.ts @@ -1,6 +1,6 @@ /* eslint-disable */ import { Entity, Column, CreateDateColumn, PrimaryGeneratedColumn, Index } from 'typeorm' -import { IChatMessage, MessageType } from '../Interface' +import { IChatMessage, MessageType } from '../../Interface' @Entity() export class ChatMessage implements IChatMessage { @@ -17,7 +17,7 @@ export class ChatMessage implements IChatMessage { @Column({ type: 'text' }) content: string - @Column({ nullable: true }) + @Column({ nullable: true, type: 'text' }) sourceDocuments?: string @CreateDateColumn() diff --git a/packages/server/src/entity/Credential.ts b/packages/server/src/database/entities/Credential.ts similarity index 85% rename from packages/server/src/entity/Credential.ts rename to packages/server/src/database/entities/Credential.ts index b724eed6..822f2584 100644 --- a/packages/server/src/entity/Credential.ts +++ b/packages/server/src/database/entities/Credential.ts @@ -1,6 +1,6 @@ /* eslint-disable */ import { Entity, Column, PrimaryGeneratedColumn, Index, CreateDateColumn, UpdateDateColumn } from 'typeorm' -import { ICredential } from '../Interface' +import { ICredential } from '../../Interface' @Entity() export class Credential implements ICredential { @@ -13,7 +13,7 @@ export class Credential implements ICredential { @Column() credentialName: string - @Column() + @Column({ type: 'text' }) encryptedData: string @CreateDateColumn() diff --git a/packages/server/src/entity/Tool.ts b/packages/server/src/database/entities/Tool.ts similarity index 80% rename from packages/server/src/entity/Tool.ts rename to packages/server/src/database/entities/Tool.ts index 011bf957..8e675eb0 100644 --- a/packages/server/src/entity/Tool.ts +++ b/packages/server/src/database/entities/Tool.ts @@ -1,6 +1,6 @@ /* eslint-disable */ import { Entity, Column, CreateDateColumn, UpdateDateColumn, PrimaryGeneratedColumn } from 'typeorm' -import { ITool } from '../Interface' +import { ITool } from '../../Interface' @Entity() export class Tool implements ITool { @@ -19,10 +19,10 @@ export class Tool implements ITool { @Column({ nullable: true }) iconSrc?: string - @Column({ nullable: true }) + @Column({ nullable: true, type: 'text' }) schema?: string - @Column({ nullable: true }) + @Column({ nullable: true, type: 'text' }) func?: string @CreateDateColumn() diff --git a/packages/server/src/database/entities/index.ts b/packages/server/src/database/entities/index.ts new file mode 100644 index 00000000..ff109863 --- /dev/null +++ b/packages/server/src/database/entities/index.ts @@ -0,0 +1,11 @@ +import { ChatFlow } from './ChatFlow' +import { ChatMessage } from './ChatMessage' +import { Credential } from './Credential' +import { Tool } from './Tool' + +export const entities = { + ChatFlow, + ChatMessage, + Credential, + Tool +} diff --git a/packages/server/src/database/migrations/mysql/1693840429259-Init.ts b/packages/server/src/database/migrations/mysql/1693840429259-Init.ts new file mode 100644 index 00000000..9d07206d --- /dev/null +++ b/packages/server/src/database/migrations/mysql/1693840429259-Init.ts @@ -0,0 +1,64 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class Init1693840429259 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS \`chat_flow\` ( + \`id\` varchar(36) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`flowData\` text NOT NULL, + \`deployed\` tinyint DEFAULT NULL, + \`isPublic\` tinyint DEFAULT NULL, + \`apikeyid\` varchar(255) DEFAULT NULL, + \`chatbotConfig\` varchar(255) DEFAULT NULL, + \`createdDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + \`updatedDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;` + ) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS \`chat_message\` ( + \`id\` varchar(36) NOT NULL, + \`role\` varchar(255) NOT NULL, + \`chatflowid\` varchar(255) NOT NULL, + \`content\` text NOT NULL, + \`sourceDocuments\` varchar(255) DEFAULT NULL, + \`createdDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + PRIMARY KEY (\`id\`), + KEY \`IDX_e574527322272fd838f4f0f3d3\` (\`chatflowid\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;` + ) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS \`credential\` ( + \`id\` varchar(36) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`credentialName\` varchar(255) NOT NULL, + \`encryptedData\` varchar(255) NOT NULL, + \`createdDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + \`updatedDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;` + ) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS \`tool\` ( + \`id\` varchar(36) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`description\` text NOT NULL, + \`color\` varchar(255) NOT NULL, + \`iconSrc\` varchar(255) DEFAULT NULL, + \`schema\` varchar(255) DEFAULT NULL, + \`func\` varchar(255) DEFAULT NULL, + \`createdDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + \`updatedDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;` + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE chat_flow`) + await queryRunner.query(`DROP TABLE chat_message`) + await queryRunner.query(`DROP TABLE credential`) + await queryRunner.query(`DROP TABLE tool`) + } +} diff --git a/packages/server/src/database/migrations/mysql/1693997791471-ModifyChatFlow.ts b/packages/server/src/database/migrations/mysql/1693997791471-ModifyChatFlow.ts new file mode 100644 index 00000000..d0023b67 --- /dev/null +++ b/packages/server/src/database/migrations/mysql/1693997791471-ModifyChatFlow.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyChatFlow1693997791471 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`chat_flow\` MODIFY \`chatbotConfig\` TEXT;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`chat_flow\` MODIFY \`chatbotConfig\` VARCHAR;`) + } +} diff --git a/packages/server/src/database/migrations/mysql/1693999022236-ModifyChatMessage.ts b/packages/server/src/database/migrations/mysql/1693999022236-ModifyChatMessage.ts new file mode 100644 index 00000000..3f6eaa4e --- /dev/null +++ b/packages/server/src/database/migrations/mysql/1693999022236-ModifyChatMessage.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyChatMessage1693999022236 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`chat_message\` MODIFY \`sourceDocuments\` TEXT;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`chat_message\` MODIFY \`sourceDocuments\` VARCHAR;`) + } +} diff --git a/packages/server/src/database/migrations/mysql/1693999261583-ModifyCredential.ts b/packages/server/src/database/migrations/mysql/1693999261583-ModifyCredential.ts new file mode 100644 index 00000000..54c33af1 --- /dev/null +++ b/packages/server/src/database/migrations/mysql/1693999261583-ModifyCredential.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyCredential1693999261583 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`credential\` MODIFY \`encryptedData\` TEXT NOT NULL;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`credential\` MODIFY \`encryptedData\` VARCHAR NOT NULL;`) + } +} diff --git a/packages/server/src/database/migrations/mysql/1694001465232-ModifyTool.ts b/packages/server/src/database/migrations/mysql/1694001465232-ModifyTool.ts new file mode 100644 index 00000000..934506cb --- /dev/null +++ b/packages/server/src/database/migrations/mysql/1694001465232-ModifyTool.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyTool1694001465232 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`tool\` MODIFY \`schema\` TEXT, MODIFY \`func\` TEXT;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`tool\` MODIFY \`schema\` VARCHAR, MODIFY \`func\` VARCHAR;`) + } +} diff --git a/packages/server/src/database/migrations/mysql/index.ts b/packages/server/src/database/migrations/mysql/index.ts new file mode 100644 index 00000000..124eb70f --- /dev/null +++ b/packages/server/src/database/migrations/mysql/index.ts @@ -0,0 +1,13 @@ +import { Init1693840429259 } from './1693840429259-Init' +import { ModifyChatFlow1693997791471 } from './1693997791471-ModifyChatFlow' +import { ModifyChatMessage1693999022236 } from './1693999022236-ModifyChatMessage' +import { ModifyCredential1693999261583 } from './1693999261583-ModifyCredential' +import { ModifyTool1694001465232 } from './1694001465232-ModifyTool' + +export const mysqlMigrations = [ + Init1693840429259, + ModifyChatFlow1693997791471, + ModifyChatMessage1693999022236, + ModifyCredential1693999261583, + ModifyTool1694001465232 +] diff --git a/packages/server/src/database/migrations/postgres/1693891895163-Init.ts b/packages/server/src/database/migrations/postgres/1693891895163-Init.ts new file mode 100644 index 00000000..3ffe055c --- /dev/null +++ b/packages/server/src/database/migrations/postgres/1693891895163-Init.ts @@ -0,0 +1,64 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class Init1693891895163 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS chat_flow ( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + "name" varchar NOT NULL, + "flowData" text NOT NULL, + deployed bool NULL, + "isPublic" bool NULL, + apikeyid varchar NULL, + "chatbotConfig" varchar NULL, + "createdDate" timestamp NOT NULL DEFAULT now(), + "updatedDate" timestamp NOT NULL DEFAULT now(), + CONSTRAINT "PK_3c7cea7d047ac4b91764574cdbf" PRIMARY KEY (id) + );` + ) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS chat_message ( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + "role" varchar NOT NULL, + chatflowid varchar NOT NULL, + "content" text NOT NULL, + "sourceDocuments" varchar NULL, + "createdDate" timestamp NOT NULL DEFAULT now(), + CONSTRAINT "PK_3cc0d85193aade457d3077dd06b" PRIMARY KEY (id) + );` + ) + await queryRunner.query(`CREATE INDEX IF NOT EXISTS "IDX_e574527322272fd838f4f0f3d3" ON chat_message USING btree (chatflowid);`) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS credential ( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + "name" varchar NOT NULL, + "credentialName" varchar NOT NULL, + "encryptedData" varchar NOT NULL, + "createdDate" timestamp NOT NULL DEFAULT now(), + "updatedDate" timestamp NOT NULL DEFAULT now(), + CONSTRAINT "PK_3a5169bcd3d5463cefeec78be82" PRIMARY KEY (id) + );` + ) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS tool ( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + "name" varchar NOT NULL, + description text NOT NULL, + color varchar NOT NULL, + "iconSrc" varchar NULL, + "schema" varchar NULL, + func varchar NULL, + "createdDate" timestamp NOT NULL DEFAULT now(), + "updatedDate" timestamp NOT NULL DEFAULT now(), + CONSTRAINT "PK_3bf5b1016a384916073184f99b7" PRIMARY KEY (id) + );` + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE chat_flow`) + await queryRunner.query(`DROP TABLE chat_message`) + await queryRunner.query(`DROP TABLE credential`) + await queryRunner.query(`DROP TABLE tool`) + } +} diff --git a/packages/server/src/database/migrations/postgres/1693995626941-ModifyChatFlow.ts b/packages/server/src/database/migrations/postgres/1693995626941-ModifyChatFlow.ts new file mode 100644 index 00000000..aee6d3fe --- /dev/null +++ b/packages/server/src/database/migrations/postgres/1693995626941-ModifyChatFlow.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyChatFlow1693995626941 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "chat_flow" ALTER COLUMN "chatbotConfig" TYPE TEXT;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "chat_flow" ALTER COLUMN "chatbotConfig" TYPE VARCHAR;`) + } +} diff --git a/packages/server/src/database/migrations/postgres/1693996694528-ModifyChatMessage.ts b/packages/server/src/database/migrations/postgres/1693996694528-ModifyChatMessage.ts new file mode 100644 index 00000000..da288783 --- /dev/null +++ b/packages/server/src/database/migrations/postgres/1693996694528-ModifyChatMessage.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyChatMessage1693996694528 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "chat_message" ALTER COLUMN "sourceDocuments" TYPE TEXT;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "chat_message" ALTER COLUMN "sourceDocuments" TYPE VARCHAR;`) + } +} diff --git a/packages/server/src/database/migrations/postgres/1693997070000-ModifyCredential.ts b/packages/server/src/database/migrations/postgres/1693997070000-ModifyCredential.ts new file mode 100644 index 00000000..ef45201a --- /dev/null +++ b/packages/server/src/database/migrations/postgres/1693997070000-ModifyCredential.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyCredential1693997070000 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "credential" ALTER COLUMN "encryptedData" TYPE TEXT;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "credential" ALTER COLUMN "encryptedData" TYPE VARCHAR;`) + } +} diff --git a/packages/server/src/database/migrations/postgres/1693997339912-ModifyTool.ts b/packages/server/src/database/migrations/postgres/1693997339912-ModifyTool.ts new file mode 100644 index 00000000..a4bf95c4 --- /dev/null +++ b/packages/server/src/database/migrations/postgres/1693997339912-ModifyTool.ts @@ -0,0 +1,11 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyTool1693997339912 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tool" ALTER COLUMN "schema" TYPE TEXT, ALTER COLUMN "func" TYPE TEXT;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tool" ALTER COLUMN "schema" TYPE VARCHAR, ALTER COLUMN "func" TYPE VARCHAR;`) + } +} diff --git a/packages/server/src/database/migrations/postgres/index.ts b/packages/server/src/database/migrations/postgres/index.ts new file mode 100644 index 00000000..2bac9f33 --- /dev/null +++ b/packages/server/src/database/migrations/postgres/index.ts @@ -0,0 +1,13 @@ +import { Init1693891895163 } from './1693891895163-Init' +import { ModifyChatFlow1693995626941 } from './1693995626941-ModifyChatFlow' +import { ModifyChatMessage1693996694528 } from './1693996694528-ModifyChatMessage' +import { ModifyCredential1693997070000 } from './1693997070000-ModifyCredential' +import { ModifyTool1693997339912 } from './1693997339912-ModifyTool' + +export const postgresMigrations = [ + Init1693891895163, + ModifyChatFlow1693995626941, + ModifyChatMessage1693996694528, + ModifyCredential1693997070000, + ModifyTool1693997339912 +] diff --git a/packages/server/src/database/migrations/sqlite/1693835579790-Init.ts b/packages/server/src/database/migrations/sqlite/1693835579790-Init.ts new file mode 100644 index 00000000..04b2e660 --- /dev/null +++ b/packages/server/src/database/migrations/sqlite/1693835579790-Init.ts @@ -0,0 +1,26 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class Init1693835579790 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "chat_flow" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "flowData" text NOT NULL, "deployed" boolean, "isPublic" boolean, "apikeyid" varchar, "chatbotConfig" varchar, "createdDate" datetime NOT NULL DEFAULT (datetime('now')), "updatedDate" datetime NOT NULL DEFAULT (datetime('now')));` + ) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "chat_message" ("id" varchar PRIMARY KEY NOT NULL, "role" varchar NOT NULL, "chatflowid" varchar NOT NULL, "content" text NOT NULL, "sourceDocuments" varchar, "createdDate" datetime NOT NULL DEFAULT (datetime('now')));` + ) + await queryRunner.query(`CREATE INDEX IF NOT EXISTS "IDX_e574527322272fd838f4f0f3d3" ON "chat_message" ("chatflowid") ;`) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "credential" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "credentialName" varchar NOT NULL, "encryptedData" varchar NOT NULL, "createdDate" datetime NOT NULL DEFAULT (datetime('now')), "updatedDate" datetime NOT NULL DEFAULT (datetime('now')));` + ) + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "tool" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "description" text NOT NULL, "color" varchar NOT NULL, "iconSrc" varchar, "schema" varchar, "func" varchar, "createdDate" datetime NOT NULL DEFAULT (datetime('now')), "updatedDate" datetime NOT NULL DEFAULT (datetime('now')));` + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE chat_flow`) + await queryRunner.query(`DROP TABLE chat_message`) + await queryRunner.query(`DROP TABLE credential`) + await queryRunner.query(`DROP TABLE tool`) + } +} diff --git a/packages/server/src/database/migrations/sqlite/1693920824108-ModifyChatFlow.ts b/packages/server/src/database/migrations/sqlite/1693920824108-ModifyChatFlow.ts new file mode 100644 index 00000000..429dc0ee --- /dev/null +++ b/packages/server/src/database/migrations/sqlite/1693920824108-ModifyChatFlow.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyChatFlow1693920824108 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "temp_chat_flow" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "flowData" text NOT NULL, "deployed" boolean, "isPublic" boolean, "apikeyid" varchar, "chatbotConfig" text, "createdDate" datetime NOT NULL DEFAULT (datetime('now')), "updatedDate" datetime NOT NULL DEFAULT (datetime('now')));` + ) + await queryRunner.query( + `INSERT INTO "temp_chat_flow" ("id", "name", "flowData", "deployed", "isPublic", "apikeyid", "chatbotConfig", "createdDate", "updatedDate") SELECT "id", "name", "flowData", "deployed", "isPublic", "apikeyid", "chatbotConfig", "createdDate", "updatedDate" FROM "chat_flow";` + ) + await queryRunner.query(`DROP TABLE chat_flow;`) + await queryRunner.query(`ALTER TABLE temp_chat_flow RENAME TO chat_flow;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE temp_chat_flow`) + } +} diff --git a/packages/server/src/database/migrations/sqlite/1693921865247-ModifyChatMessage.ts b/packages/server/src/database/migrations/sqlite/1693921865247-ModifyChatMessage.ts new file mode 100644 index 00000000..94cd6e0e --- /dev/null +++ b/packages/server/src/database/migrations/sqlite/1693921865247-ModifyChatMessage.ts @@ -0,0 +1,19 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyChatMessage1693921865247 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "temp_chat_message" ("id" varchar PRIMARY KEY NOT NULL, "role" varchar NOT NULL, "chatflowid" varchar NOT NULL, "content" text NOT NULL, "sourceDocuments" text, "createdDate" datetime NOT NULL DEFAULT (datetime('now')));` + ) + await queryRunner.query( + `INSERT INTO "temp_chat_message" ("id", "role", "chatflowid", "content", "sourceDocuments", "createdDate") SELECT "id", "role", "chatflowid", "content", "sourceDocuments", "createdDate" FROM "chat_message";` + ) + await queryRunner.query(`DROP TABLE chat_message;`) + await queryRunner.query(`ALTER TABLE temp_chat_message RENAME TO chat_message;`) + await queryRunner.query(`CREATE INDEX IF NOT EXISTS "IDX_e574527322272fd838f4f0f3d3" ON "chat_message" ("chatflowid") ;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE temp_chat_message`) + } +} diff --git a/packages/server/src/database/migrations/sqlite/1693923551694-ModifyCredential.ts b/packages/server/src/database/migrations/sqlite/1693923551694-ModifyCredential.ts new file mode 100644 index 00000000..fccb3c18 --- /dev/null +++ b/packages/server/src/database/migrations/sqlite/1693923551694-ModifyCredential.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyCredential1693923551694 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "temp_credential" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "credentialName" varchar NOT NULL, "encryptedData" text NOT NULL, "createdDate" datetime NOT NULL DEFAULT (datetime('now')), "updatedDate" datetime NOT NULL DEFAULT (datetime('now')));` + ) + await queryRunner.query( + `INSERT INTO "temp_credential" ("id", "name", "credentialName", "encryptedData", "createdDate", "updatedDate") SELECT "id", "name", "credentialName", "encryptedData", "createdDate", "updatedDate" FROM "credential";` + ) + await queryRunner.query(`DROP TABLE credential;`) + await queryRunner.query(`ALTER TABLE temp_credential RENAME TO credential;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE temp_credential`) + } +} diff --git a/packages/server/src/database/migrations/sqlite/1693924207475-ModifyTool.ts b/packages/server/src/database/migrations/sqlite/1693924207475-ModifyTool.ts new file mode 100644 index 00000000..ad27eb12 --- /dev/null +++ b/packages/server/src/database/migrations/sqlite/1693924207475-ModifyTool.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class ModifyTool1693924207475 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "temp_tool" ("id" varchar PRIMARY KEY NOT NULL, "name" varchar NOT NULL, "description" text NOT NULL, "color" varchar NOT NULL, "iconSrc" varchar, "schema" text, "func" text, "createdDate" datetime NOT NULL DEFAULT (datetime('now')), "updatedDate" datetime NOT NULL DEFAULT (datetime('now')));` + ) + await queryRunner.query( + `INSERT INTO "temp_tool" ("id", "name", "description", "color", "iconSrc", "schema", "func", "createdDate", "updatedDate") SELECT "id", "name", "description", "color", "iconSrc", "schema", "func", "createdDate", "updatedDate" FROM "tool";` + ) + await queryRunner.query(`DROP TABLE tool;`) + await queryRunner.query(`ALTER TABLE temp_tool RENAME TO tool;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE temp_tool`) + } +} diff --git a/packages/server/src/database/migrations/sqlite/index.ts b/packages/server/src/database/migrations/sqlite/index.ts new file mode 100644 index 00000000..c3c1fe7a --- /dev/null +++ b/packages/server/src/database/migrations/sqlite/index.ts @@ -0,0 +1,13 @@ +import { Init1693835579790 } from './1693835579790-Init' +import { ModifyChatFlow1693920824108 } from './1693920824108-ModifyChatFlow' +import { ModifyChatMessage1693921865247 } from './1693921865247-ModifyChatMessage' +import { ModifyCredential1693923551694 } from './1693923551694-ModifyCredential' +import { ModifyTool1693924207475 } from './1693924207475-ModifyTool' + +export const sqliteMigrations = [ + Init1693835579790, + ModifyChatFlow1693920824108, + ModifyChatMessage1693921865247, + ModifyCredential1693923551694, + ModifyTool1693924207475 +] diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 66c7b000..81dbbcb4 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -48,10 +48,10 @@ import { import { cloneDeep, omit } from 'lodash' import { getDataSource } from './DataSource' import { NodesPool } from './NodesPool' -import { ChatFlow } from './entity/ChatFlow' -import { ChatMessage } from './entity/ChatMessage' -import { Credential } from './entity/Credential' -import { Tool } from './entity/Tool' +import { ChatFlow } from './database/entities/ChatFlow' +import { ChatMessage } from './database/entities/ChatMessage' +import { Credential } from './database/entities/Credential' +import { Tool } from './database/entities/Tool' import { ChatflowPool } from './ChatflowPool' import { ICommonObject, INodeOptionsValue } from 'flowise-components' @@ -71,6 +71,9 @@ export class App { .then(async () => { logger.info('📦 [server]: Data Source has been initialized!') + // Run Migrations Scripts + await this.AppDataSource.runMigrations({ transaction: 'each' }) + // Initialize nodes pool this.nodesPool = new NodesPool() await this.nodesPool.initialize() diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts index b95dd301..73c748a3 100644 --- a/packages/server/src/utils/index.ts +++ b/packages/server/src/utils/index.ts @@ -30,10 +30,10 @@ import { import { scryptSync, randomBytes, timingSafeEqual } from 'crypto' import { lib, PBKDF2, AES, enc } from 'crypto-js' -import { ChatFlow } from '../entity/ChatFlow' -import { ChatMessage } from '../entity/ChatMessage' -import { Credential } from '../entity/Credential' -import { Tool } from '../entity/Tool' +import { ChatFlow } from '../database/entities/ChatFlow' +import { ChatMessage } from '../database/entities/ChatMessage' +import { Credential } from '../database/entities/Credential' +import { Tool } from '../database/entities/Tool' import { DataSource } from 'typeorm' const QUESTION_VAR_PREFIX = 'question'