diff --git a/packages/server/src/DataSource.ts b/packages/server/src/DataSource.ts index b0d56477..a1d37996 100644 --- a/packages/server/src/DataSource.ts +++ b/packages/server/src/DataSource.ts @@ -1,26 +1,24 @@ 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 { InitSqlite1693809869231 } from './database/migrations/1693809869231-initSqlite' 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: [InitSqlite1693809869231] }) break case 'mysql': @@ -32,8 +30,9 @@ export const init = async (): Promise => { password: process.env.DATABASE_PASSWORD, database: process.env.DATABASE_NAME, charset: 'utf8mb4', - synchronize, - entities: [ChatFlow, ChatMessage, Tool, Credential], + synchronize: false, + migrationsRun: false, + entities: Object.values(entities), migrations: [] }) break @@ -45,8 +44,9 @@ 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], + synchronize: false, + migrationsRun: false, + entities: Object.values(entities), migrations: [] }) break @@ -55,9 +55,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: [InitSqlite1693809869231] }) break } diff --git a/packages/server/src/entity/ChatFlow.ts b/packages/server/src/database/entities/ChatFlow.ts similarity index 93% rename from packages/server/src/entity/ChatFlow.ts rename to packages/server/src/database/entities/ChatFlow.ts index 4c37e083..a1a32a88 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 { diff --git a/packages/server/src/entity/ChatMessage.ts b/packages/server/src/database/entities/ChatMessage.ts similarity index 88% rename from packages/server/src/entity/ChatMessage.ts rename to packages/server/src/database/entities/ChatMessage.ts index 8123020c..23804846 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 { diff --git a/packages/server/src/entity/Credential.ts b/packages/server/src/database/entities/Credential.ts similarity index 90% rename from packages/server/src/entity/Credential.ts rename to packages/server/src/database/entities/Credential.ts index b724eed6..e77711dc 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 { diff --git a/packages/server/src/entity/Tool.ts b/packages/server/src/database/entities/Tool.ts similarity index 93% rename from packages/server/src/entity/Tool.ts rename to packages/server/src/database/entities/Tool.ts index 011bf957..d459eee3 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 { 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/1693809869231-initSqlite.ts b/packages/server/src/database/migrations/1693809869231-initSqlite.ts new file mode 100644 index 00000000..78af741d --- /dev/null +++ b/packages/server/src/database/migrations/1693809869231-initSqlite.ts @@ -0,0 +1,29 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class InitSqlite1693809869231 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + console.info('started migration query') + await queryRunner.query( + `CREATE TABLE "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 "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 "IDX_e574527322272fd838f4f0f3d3" ON "chat_message" ("chatflowid") ;`) + await queryRunner.query( + `CREATE TABLE "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 "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')));` + ) + console.info('Finish migration query') + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "chat_flow"`) + await queryRunner.query(`DROP INDEX "IDX_chat_messagee574527322272fd838f4f0f3d3"`) + 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/index.ts b/packages/server/src/index.ts index 66c7b000..1e8dc83c 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,11 @@ export class App { .then(async () => { logger.info('📦 [server]: Data Source has been initialized!') + //Migrations + console.info(`start migration`) + await this.AppDataSource.runMigrations({ transaction: 'each' }) + console.info(`finish migration`) + // 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'