diff --git a/.gitignore b/.gitignore index 53113035..f25cbffd 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,8 @@ plugin/**/dist plugin/oneapi/test/fixtures/modules/*/oneapi plugin/dal/test/fixtures/modules/*/dal/ +core/dal-runtime/test/fixtures/modules/*/dal +!core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/dal/dao/FooDAO.ts plugin/tegg/test/fixtures/apps/**/*.js !core/common-util/test/fixtures/**/node_modules diff --git a/core/dal-runtime/src/CodeGenerator.ts b/core/dal-runtime/src/CodeGenerator.ts index 7140bd3b..a4980fad 100644 --- a/core/dal-runtime/src/CodeGenerator.ts +++ b/core/dal-runtime/src/CodeGenerator.ts @@ -94,16 +94,19 @@ export class CodeGenerator { templates: Templates.BASE_DAO, filePath: paths.baseBizDAO, beautify: true, + overwrite: true, }, { templates: Templates.DAO, filePath: paths.bizDAO, beautify: true, + overwrite: false, }, { templates: Templates.EXTENSION, filePath: paths.extension, beautify: false, + overwrite: true, }]; - for (const { templates, filePath, beautify } of codes) { + for (const { templates, filePath, beautify, overwrite } of codes) { await fs.mkdir(path.dirname(filePath), { recursive: true, }); @@ -127,6 +130,14 @@ export class CodeGenerator { .replace(/Partial( )*<( )*(.+?)( )*>/g, 'Partial<$3>') .replace(/DataSource( )*<( )*(.+?)( )*>/g, 'DataSource<$3>') .replace(/ \? :/g, '?:'); + if (overwrite !== true) { + try { + await fs.access(filePath); + continue; + } catch { + // file not exists + } + } await fs.writeFile(filePath, beautified, 'utf8'); } } diff --git a/core/dal-runtime/test/CodeGenerator.test.ts b/core/dal-runtime/test/CodeGenerator.test.ts index 39a16036..ebbc2b9a 100644 --- a/core/dal-runtime/test/CodeGenerator.test.ts +++ b/core/dal-runtime/test/CodeGenerator.test.ts @@ -1,5 +1,6 @@ import assert from 'node:assert'; import path from 'node:path'; +import fs from 'node:fs/promises'; import { Foo } from './fixtures/modules/generate_codes/Foo'; import { MultiPrimaryKey } from './fixtures/modules/generate_codes/MultiPrimaryKey'; import { TableModel } from '@eggjs/dal-decorator'; @@ -19,4 +20,19 @@ describe('test/CodeGenerator.test.ts', () => { await generator.generate(multiPrimaryKeyTableModel); assert(fooModel); }); + + it('should not overwrite Dao file', async () => { + const generator = new CodeGenerator({ + moduleDir: path.join(__dirname, './fixtures/modules/generate_codes_not_overwrite_dao'), + moduleName: 'dal', + dalPkg: '@eggjs/dal-decorator', + }); + const fooModel = TableModel.build(Foo); + await generator.generate(fooModel); + + const multiPrimaryKeyTableModel = TableModel.build(MultiPrimaryKey); + await generator.generate(multiPrimaryKeyTableModel); + const daoFile = await fs.readFile(path.join(__dirname, './fixtures/modules/generate_codes_not_overwrite_dao/dal/dao/FooDAO.ts'), 'utf8'); + assert(/customFind/.test(daoFile)); + }); }); diff --git a/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/Foo.ts b/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/Foo.ts new file mode 100644 index 00000000..5e1a3493 --- /dev/null +++ b/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/Foo.ts @@ -0,0 +1,323 @@ +import { + Column, + ColumnType, + Geometry, + GeometryCollection, + Index, + IndexType, + Line, + IndexStoreType, + MultiLine, + MultiPoint, + MultiPolygon, + Point, + Polygon, + Table, +} from '@eggjs/dal-decorator'; + +@Table({ + name: 'egg_foo', + comment: 'foo table', + // autoExtendSize: 1024, + // autoIncrement: 100, + // avgRowLength: 1024, + characterSet: 'utf8mb4', + collate: 'utf8mb4_unicode_ci', + // compression: CompressionType.ZLIB, + // encryption: true, + // engine: 'NDB', + // engineAttribute: '{"key":"value"}', + // secondaryEngineAttribute: '{"key2":"value2"}', + // insertMethod: InsertMethod.FIRST, + // keyBlockSize: 1024, + // maxRows: 1000000, + // minRows: 100, + // rowFormat: RowFormat.COMPRESSED, +}) +@Index({ + keys: [ 'name', 'col1' ], + type: IndexType.UNIQUE, + storeType: IndexStoreType.BTREE, + comment: 'index comment\n', + // engineAttribute: '{"key":"value"}', + // secondaryEngineAttribute: '{"key2":"value2"}', +}) +@Index({ + keys: [ 'col1' ], + type: IndexType.FULLTEXT, + comment: 'index comment\n', + // engineAttribute: '{"key":"value"}', + // secondaryEngineAttribute: '{"key2":"value2"}', + // parser: 'foo', +}) +export class Foo { + @Column({ + type: ColumnType.INT, + }, { + primaryKey: true, + autoIncrement: true, + comment: 'the primary key', + }) + id: number; + + @Column({ + type: ColumnType.VARCHAR, + length: 100, + }, { + uniqueKey: true, + }) + name: string; + + @Column({ + type: ColumnType.VARCHAR, + length: 100, + }, { + name: 'col1', + }) + col1: string; + + @Column({ + type: ColumnType.BIT, + length: 10, + }) + bitColumn: Buffer; + + @Column({ + type: ColumnType.BOOL, + }) + boolColumn: 0 | 1; + + @Column({ + type: ColumnType.TINYINT, + length: 5, + unsigned: true, + zeroFill: true, + }) + tinyIntColumn: number; + + @Column({ + type: ColumnType.SMALLINT, + length: 5, + unsigned: true, + zeroFill: true, + }) + smallIntColumn: number; + + @Column({ + type: ColumnType.MEDIUMINT, + length: 5, + unsigned: true, + zeroFill: true, + }) + mediumIntColumn: number; + + @Column({ + type: ColumnType.INT, + length: 5, + unsigned: true, + zeroFill: true, + }) + intColumn: number; + + @Column({ + type: ColumnType.BIGINT, + length: 5, + unsigned: true, + zeroFill: true, + }) + bigIntColumn: string; + + @Column({ + type: ColumnType.DECIMAL, + length: 10, + fractionalLength: 5, + unsigned: true, + zeroFill: true, + }) + decimalColumn: string; + + @Column({ + type: ColumnType.FLOAT, + length: 10, + fractionalLength: 5, + unsigned: true, + zeroFill: true, + }) + floatColumn: number; + + @Column({ + type: ColumnType.DOUBLE, + length: 10, + fractionalLength: 5, + unsigned: true, + zeroFill: true, + }) + doubleColumn: number; + + @Column({ + type: ColumnType.DATE, + }) + dateColumn: Date; + + @Column({ + type: ColumnType.DATETIME, + precision: 3, + }) + dateTimeColumn: Date; + + @Column({ + type: ColumnType.TIMESTAMP, + precision: 3, + }) + timestampColumn: Date; + + @Column({ + type: ColumnType.TIME, + precision: 3, + }) + timeColumn: string; + + @Column({ + type: ColumnType.YEAR, + }) + yearColumn: number; + + @Column({ + type: ColumnType.VARCHAR, + length: 100, + characterSet: 'utf8mb4', + collate: 'utf8mb4_unicode_ci', + }) + varCharColumn: string; + + @Column({ + type: ColumnType.BINARY, + }) + binaryColumn: Buffer; + + @Column({ + type: ColumnType.VARBINARY, + length: 100, + }) + varBinaryColumn: Buffer; + + @Column({ + type: ColumnType.TINYBLOB, + }) + tinyBlobColumn: Buffer; + + @Column({ + type: ColumnType.TINYTEXT, + characterSet: 'utf8mb4', + collate: 'utf8mb4_unicode_ci', + }) + tinyTextColumn: string; + + @Column({ + type: ColumnType.BLOB, + length: 100, + }) + blobColumn: Buffer; + + @Column({ + type: ColumnType.TEXT, + length: 100, + characterSet: 'utf8mb4', + collate: 'utf8mb4_unicode_ci', + }) + textColumn: string; + + @Column({ + type: ColumnType.MEDIUMBLOB, + }) + mediumBlobColumn: Buffer; + + @Column({ + type: ColumnType.LONGBLOB, + }) + longBlobColumn: Buffer; + + @Column({ + type: ColumnType.MEDIUMTEXT, + characterSet: 'utf8mb4', + collate: 'utf8mb4_unicode_ci', + }) + mediumTextColumn: string; + + @Column({ + type: ColumnType.LONGTEXT, + characterSet: 'utf8mb4', + collate: 'utf8mb4_unicode_ci', + }) + longTextColumn: string; + + @Column({ + type: ColumnType.ENUM, + enums: [ 'A', 'B' ], + characterSet: 'utf8mb4', + collate: 'utf8mb4_unicode_ci', + }) + enumColumn: string; + + @Column({ + type: ColumnType.SET, + enums: [ 'A', 'B' ], + characterSet: 'utf8mb4', + collate: 'utf8mb4_unicode_ci', + }) + setColumn: string; + + @Column({ + type: ColumnType.GEOMETRY, + // SRID: 4326, + }) + geometryColumn: Geometry; + + + @Column({ + type: ColumnType.POINT, + // SRID: 4326, + }) + pointColumn: Point; + + @Column({ + type: ColumnType.LINESTRING, + // SRID: 4326, + }) + lineStringColumn: Line; + + @Column({ + type: ColumnType.POLYGON, + // SRID: 4326, + }) + polygonColumn: Polygon; + + @Column({ + type: ColumnType.MULTIPOINT, + // SRID: 4326, + }) + multipointColumn: MultiPoint; + + @Column({ + type: ColumnType.MULTILINESTRING, + // SRID: 4326, + }) + multiLineStringColumn: MultiLine; + + @Column({ + type: ColumnType.MULTIPOLYGON, + // SRID: 4326, + }) + multiPolygonColumn: MultiPolygon; + + @Column({ + type: ColumnType.GEOMETRYCOLLECTION, + // SRID: 4326, + }) + geometryCollectionColumn: GeometryCollection; + + @Column({ + type: ColumnType.JSON, + }) + jsonColumn: object; +} diff --git a/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/dal/dao/FooDAO.ts b/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/dal/dao/FooDAO.ts new file mode 100644 index 00000000..f6d7956f --- /dev/null +++ b/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/dal/dao/FooDAO.ts @@ -0,0 +1,17 @@ +import { SingletonProto, AccessLevel } from '@eggjs/tegg'; +import { BaseFooDAO } from './base/BaseFooDAO'; + +/** + * FooDAO 类 + * @class FooDAO + * @classdesc 在此扩展关于 Foo 数据的一切操作 + * @extends BaseFooDAO + */ +@SingletonProto({ + accessLevel: AccessLevel.PUBLIC, +}) +export default class FooDAO extends BaseFooDAO { + async customFind() { + // ... do something + } +} diff --git a/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/package.json b/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/package.json new file mode 100644 index 00000000..1769916d --- /dev/null +++ b/core/dal-runtime/test/fixtures/modules/generate_codes_not_overwrite_dao/package.json @@ -0,0 +1,6 @@ +{ + "name": "dal", + "eggModule": { + "name": "dal" + } +}