diff --git a/package.json b/package.json index c748d4e..8c71385 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eojuk", - "version": "0.9.0", + "version": "0.9.1", "description": "", "keywords": [ "mysql", diff --git a/src/output/dapper.ts b/src/output/dapper.ts new file mode 100644 index 0000000..99581b6 --- /dev/null +++ b/src/output/dapper.ts @@ -0,0 +1,117 @@ +import Column from "../types/column"; +import { IOption } from "../types/option"; +import { IEmmiter } from "../interfaces/emitter"; +import Source from "../types/source"; +import Table from "../types/table"; +import { convertNameCaseByOption } from "../util.ts/name"; +import { TAB } from "../util.ts/tab"; +import { escapeDoubleQuote } from "../util.ts/escape"; + +const importTemplate = `// If under EE 9, change jakarta to javax +import jakarta.annotation.*; +import jakarta.persistence.*; +import jakarta.persistence.Table; + +import org.hibernate.annotations.*; +import java.time.LocalDateTime; +`; + +export class DapperEmitter implements IEmmiter { + private option: IOption; + + // 컬럼 필드 코드 생성 + private generateColumn(column: Column) { + const columnFieldName = convertNameCaseByOption( + this.option.outputFieldNameCase, + column.name + ); + + const hasCreatedAt = column.name == this.option.autoAddCreatedAt; + const hasUpdatedAt = column.name == this.option.autoAddUpdatedAt; + // const hasDeletedAt = column.name == this.option.autoAddDeletedAt + + // PrimaryKey 강제 추가 옵션 + if (column.name == this.option.autoAddPrimaryKey) { + column.isPrimaryKey = true; + } + + const createdAt = hasCreatedAt ? `\n${TAB}@CreationTimestamp` : ""; + const updatedAt = hasUpdatedAt ? `\n${TAB}@UpdateTimestamp` : ""; + const deletedAt = ""; // hibernate에는 해당 기능이 없음 + + const primaryKey = column.isPrimaryKey ? `\n${TAB}@Id` : ""; + + const autoIncrement = column.isAutoIncrement + ? `\n${TAB}@GeneratedValue(strategy = GenerationType.IDENTITY)` + : ""; + + const defaultValue = column.default + ? `\n${TAB}@ColumnDefault("${escapeDoubleQuote(column.default)}")` + : ""; + + const comment = column.comment + ? `\n${TAB}@Comment("${escapeDoubleQuote(column.comment)}")` + : ""; + + //const dataType = this.dbTypeToDataType(column.dbType); + + const columnAnnotation = `\n${TAB}@Column(name = "${escapeDoubleQuote( + column.name + )}")`; + + const notNullAnnotaion = column.isNotNull + ? `\n${TAB}@Nonnull` + : `\n${TAB}@Nullable`; + + return `${primaryKey}${autoIncrement}${columnAnnotation}${notNullAnnotaion}${comment}${defaultValue}${createdAt}${updatedAt}${deletedAt} +${TAB}${column.javaType} ${columnFieldName};`; + } + + // 테이블 클래스 코드 생성 + private generateTableCode(table: Table) { + const hasDatabaseName = this.option.databaseName != null; + + const tableClassName = convertNameCaseByOption( + this.option.outputClassNameCase, + table.tableName + ); + + const schema = hasDatabaseName + ? `, schema = "\\"${this.option.databaseName}\\""` + : ""; + + return `@Entity() +@Table(name = "\\"${table.tableName}\\""${schema}) +public class ${tableClassName} { +${table.columns.map((column) => this.generateColumn(column)).join("\n")} +}`; + } + + emit( + tables: Table[], + option: IOption = { + sourceSplit: true, + outputClassNameCase: "PASCAL", + outputFieldNameCase: "CAMEL", + } + ): Source[] { + this.option = option; + + if (option?.sourceSplit) { + return tables.map((table) => ({ + sourceName: table.tableName, + source: importTemplate + "\n" + this.generateTableCode(table), + })); + } else { + return [ + { + sourceName: "all", + source: + importTemplate + + "\n" + + tables.map((table) => this.generateTableCode(table)).join("\n\n"), + }, + ]; + } + } +} diff --git a/src/output/jpa-java.ts b/src/output/jpa-java.ts index d93d783..79fb672 100644 --- a/src/output/jpa-java.ts +++ b/src/output/jpa-java.ts @@ -7,8 +7,7 @@ import { convertNameCaseByOption } from "../util.ts/name"; import { TAB } from "../util.ts/tab"; import { escapeDoubleQuote } from "../util.ts/escape"; -const importTemplate = ` -// If under EE 9, change jakarta to javax +const importTemplate = `// If under EE 9, change jakarta to javax import jakarta.annotation.*; import jakarta.persistence.*; import jakarta.persistence.Table; diff --git a/src/output/jpa-kotlin.ts b/src/output/jpa-kotlin.ts index 64de475..8f5d0bf 100644 --- a/src/output/jpa-kotlin.ts +++ b/src/output/jpa-kotlin.ts @@ -7,8 +7,7 @@ import { convertNameCaseByOption } from "../util.ts/name"; import { TAB } from "../util.ts/tab"; import { escapeDoubleQuote } from "../util.ts/escape"; -const importTemplate = ` -// If under EE 9, change jakarta to javax +const importTemplate = `// If under EE 9, change jakarta to javax import jakarta.annotation.* import jakarta.persistence.* import jakarta.persistence.Table diff --git a/src/output/sequelize-typescript.ts b/src/output/sequelize-typescript.ts index 8b085bb..65eab57 100644 --- a/src/output/sequelize-typescript.ts +++ b/src/output/sequelize-typescript.ts @@ -4,14 +4,13 @@ import { IEmmiter } from "../interfaces/emitter"; import Source from "../types/source"; import Table from "../types/table"; import { - convertNameCaseByOption, - toCamelCase, - toSnakeCase, + convertNameCaseByOption, + toCamelCase, + toSnakeCase, } from "../util.ts/name"; import { TAB } from "../util.ts/tab"; -const importTemplate = ` -import { literal } from 'sequelize'; +const importTemplate = `import { literal } from 'sequelize'; import { Model, Table, @@ -37,86 +36,89 @@ import { `; export class SequelizeTypescriptEmitter implements IEmmiter { - private option: IOption; - - private dbTypeToDataType(dbtype: string): string { - if (["varchar", "text", "char"].includes(dbtype.toLowerCase())) { - return "DataType.STRING"; - } else if (["bool", "boolean"].includes(dbtype.toLowerCase())) { - return "DataType.BOOLEAN"; - } else if (["uuid"].includes(dbtype.toLowerCase())) { - return "DataType.UUID"; - } else if ( - ["int", "int2", "int4", "int8", "bigint"].includes( - dbtype.toLowerCase() - ) - ) { - return "DataType.INTEGER"; - } else { - return `'${dbtype}'`; - } + private option: IOption; + + private dbTypeToDataType(dbtype: string): string { + if (["varchar", "text", "char"].includes(dbtype.toLowerCase())) { + return "DataType.STRING"; + } else if (["bool", "boolean"].includes(dbtype.toLowerCase())) { + return "DataType.BOOLEAN"; + } else if (["uuid"].includes(dbtype.toLowerCase())) { + return "DataType.UUID"; + } else if ( + ["int", "int2", "int4", "int8", "bigint"].includes(dbtype.toLowerCase()) + ) { + return "DataType.INTEGER"; + } else { + return `'${dbtype}'`; + } + } + + // 컬럼 필드 코드 생성 + private generateColumn(column: Column) { + const columnFieldName = convertNameCaseByOption( + this.option.outputFieldNameCase, + column.name + ); + + const hasCreatedAt = column.name == this.option.autoAddCreatedAt; + const hasUpdatedAt = column.name == this.option.autoAddUpdatedAt; + const hasDeletedAt = column.name == this.option.autoAddDeletedAt; + + // PrimaryKey 강제 추가 옵션 + if (column.name == this.option.autoAddPrimaryKey) { + column.isPrimaryKey = true; } - // 컬럼 필드 코드 생성 - private generateColumn(column: Column) { - const columnFieldName = convertNameCaseByOption( - this.option.outputFieldNameCase, - column.name - ); - - const hasCreatedAt = column.name == this.option.autoAddCreatedAt - const hasUpdatedAt = column.name == this.option.autoAddUpdatedAt - const hasDeletedAt = column.name == this.option.autoAddDeletedAt - - // PrimaryKey 강제 추가 옵션 - if(column.name == this.option.autoAddPrimaryKey) { - column.isPrimaryKey = true; - } - - const createdAt = hasCreatedAt ? `\n${TAB}@CreatedAt` : ""; - const updatedAt = hasUpdatedAt ? `\n${TAB}@UpdatedAt` : ""; - const deletedAt = hasDeletedAt ? `\n${TAB}@DeletedAt` : ""; + const createdAt = hasCreatedAt ? `\n${TAB}@CreatedAt` : ""; + const updatedAt = hasUpdatedAt ? `\n${TAB}@UpdatedAt` : ""; + const deletedAt = hasDeletedAt ? `\n${TAB}@DeletedAt` : ""; - const primaryKey = column.isPrimaryKey - ? `primaryKey: true, \n${TAB}${TAB}` - : ""; + const primaryKey = column.isPrimaryKey + ? `primaryKey: true, \n${TAB}${TAB}` + : ""; - const autoIncrement = column.isAutoIncrement - ? `autoIncrement: true, \n${TAB}${TAB}` - : ""; + const autoIncrement = column.isAutoIncrement + ? `autoIncrement: true, \n${TAB}${TAB}` + : ""; - const defaultValue = column.default - ? `\n${TAB}${TAB}default: literal("${column.default.replace( - '"', - '\\"' - )}"),` - : ""; + const defaultValue = column.default + ? `\n${TAB}${TAB}default: literal("${column.default.replace( + '"', + '\\"' + )}"),` + : ""; - const dataType = this.dbTypeToDataType(column.dbType); + const dataType = this.dbTypeToDataType(column.dbType); - return ` @Comment(\`${column.comment ?? ""}\`)${createdAt}${updatedAt}${deletedAt} + return ` @Comment(\`${ + column.comment ?? "" + }\`)${createdAt}${updatedAt}${deletedAt} @Column({ ${primaryKey}${autoIncrement}field: '${column.name}', type: ${dataType}, allowNull: ${!column.isNotNull},${defaultValue} }) ${columnFieldName}: ${column.tsType};`; - } + } - // 테이블 클래스 코드 생성 - private generateTableCode(table: Table) { - const hasCreatedAt = table.columns.find(e=>e.name == this.option.autoAddCreatedAt) != null; - const hasUpdatedAt = table.columns.find(e=>e.name == this.option.autoAddUpdatedAt) != null; - const hasDeletedAt = table.columns.find(e=>e.name == this.option.autoAddDeletedAt) != null; + // 테이블 클래스 코드 생성 + private generateTableCode(table: Table) { + const hasCreatedAt = + table.columns.find((e) => e.name == this.option.autoAddCreatedAt) != null; + const hasUpdatedAt = + table.columns.find((e) => e.name == this.option.autoAddUpdatedAt) != null; + const hasDeletedAt = + table.columns.find((e) => e.name == this.option.autoAddDeletedAt) != null; - const hasDatabaseName = this.option.databaseName != null + const hasDatabaseName = this.option.databaseName != null; - const tableClassName = convertNameCaseByOption( - this.option.outputClassNameCase, - table.tableName - ); + const tableClassName = convertNameCaseByOption( + this.option.outputClassNameCase, + table.tableName + ); - return `@Table({ + return `@Table({ tableName: '${table.tableName}', paranoid: ${hasDeletedAt}, freezeTableName: true, @@ -124,40 +126,40 @@ export class SequelizeTypescriptEmitter implements IEmmiter { createdAt: ${hasCreatedAt}, updatedAt: ${hasUpdatedAt}, deletedAt: ${hasDeletedAt}, - ${hasDatabaseName ? '' : '// '}schema: '${this.option.databaseName ?? 'public'}', + ${hasDatabaseName ? "" : "// "}schema: '${ + this.option.databaseName ?? "public" + }', }) export class ${tableClassName} extends Model { ${table.columns.map((column) => this.generateColumn(column)).join("\n\n")} }`; + } + + emit( + tables: Table[], + option: IOption = { + sourceSplit: true, + outputClassNameCase: "PASCAL", + outputFieldNameCase: "CAMEL", } - - emit( - tables: Table[], - option: IOption = { - sourceSplit: true, - outputClassNameCase: "PASCAL", - outputFieldNameCase: "CAMEL", - } - ): Source[] { - this.option = option; - - if (option?.sourceSplit) { - return tables.map((table) => ({ - sourceName: table.tableName, - source: importTemplate + "\n" + this.generateTableCode(table), - })); - } else { - return [ - { - sourceName: "all", - source: - importTemplate + - "\n" + - tables - .map((table) => this.generateTableCode(table)) - .join("\n\n"), - }, - ]; - } + ): Source[] { + this.option = option; + + if (option?.sourceSplit) { + return tables.map((table) => ({ + sourceName: table.tableName, + source: importTemplate + "\n" + this.generateTableCode(table), + })); + } else { + return [ + { + sourceName: "all", + source: + importTemplate + + "\n" + + tables.map((table) => this.generateTableCode(table)).join("\n\n"), + }, + ]; } + } } diff --git a/src/output/sqlalchemy.ts b/src/output/sqlalchemy.ts index ac3e62d..682a64d 100644 --- a/src/output/sqlalchemy.ts +++ b/src/output/sqlalchemy.ts @@ -7,8 +7,7 @@ import { convertNameCaseByOption } from "../util.ts/name"; import { TAB } from "../util.ts/tab"; import { escapeDoubleQuote } from "../util.ts/escape"; -const importTemplate = ` -from sqlalchemy import Column +const importTemplate = `from sqlalchemy import Column from sqlalchemy import String, Integer, Double, Float, BigInteger, DateTime, Boolean from sqlalchemy.orm import declarative_base diff --git a/src/output/typeorm.ts b/src/output/typeorm.ts index a1227db..62a012c 100644 --- a/src/output/typeorm.ts +++ b/src/output/typeorm.ts @@ -4,70 +4,67 @@ import { IOption } from "../types/option"; import Source from "../types/source"; import Table from "../types/table"; import { - convertNameCaseByOption, - toCamelCase, - toPascalCase, - toSnakeCase, + convertNameCaseByOption, + toCamelCase, + toPascalCase, + toSnakeCase, } from "../util.ts/name"; import { TAB } from "../util.ts/tab"; -const importTemplate = ` -import {Entity, PrimaryGeneratedColumn, Column, Generated} from "typeorm"; +const importTemplate = `import {Entity, PrimaryGeneratedColumn, Column, Generated} from "typeorm"; `; export class TypeOrmEmitter implements IEmmiter { - private option: IOption; + private option: IOption; - // 컬럼 필드 코드 생성 - private generateColumn(column: Column) { - const columnFieldName = convertNameCaseByOption( - this.option.outputFieldNameCase, - column.name - ); + // 컬럼 필드 코드 생성 + private generateColumn(column: Column) { + const columnFieldName = convertNameCaseByOption( + this.option.outputFieldNameCase, + column.name + ); - let defaultValue = column.default - ? `\n${TAB}${TAB}default: "${column.default?.replace('"', '\\"')}",` - : ""; + let defaultValue = column.default + ? `\n${TAB}${TAB}default: "${column.default?.replace('"', '\\"')}",` + : ""; - let comment = column.default - ? `\n${TAB}${TAB}comment: "${ - column.comment?.replace('"', '\\"') ?? "" - }",` - : ""; + let comment = column.default + ? `\n${TAB}${TAB}comment: "${column.comment?.replace('"', '\\"') ?? ""}",` + : ""; - let nullable = column.default - ? `\n${TAB}${TAB}nullable: ${!column.isNotNull},` - : ""; + let nullable = column.default + ? `\n${TAB}${TAB}nullable: ${!column.isNotNull},` + : ""; - let columnDecorator = "Column"; + let columnDecorator = "Column"; - if (column.isPrimaryKey && column.isAutoIncrement) { - columnDecorator = "PrimaryGeneratedColumn"; - defaultValue = ""; - nullable = ""; - } else if (column.isPrimaryKey) { - columnDecorator = "PrimaryColumn"; - nullable = ""; - } else if (column.isAutoIncrement) { - columnDecorator = "Generated"; - defaultValue = ""; - } + if (column.isPrimaryKey && column.isAutoIncrement) { + columnDecorator = "PrimaryGeneratedColumn"; + defaultValue = ""; + nullable = ""; + } else if (column.isPrimaryKey) { + columnDecorator = "PrimaryColumn"; + nullable = ""; + } else if (column.isAutoIncrement) { + columnDecorator = "Generated"; + defaultValue = ""; + } - return ` @${columnDecorator}({ + return ` @${columnDecorator}({ name: '${column.name}', type: '${column.dbType.toLowerCase()}',${nullable}${defaultValue}${comment} }) ${columnFieldName}: ${column.tsType};`; - } + } - // 테이블 클래스 코드 생성 - private generateTableCode(table: Table) { - const tableClassName = convertNameCaseByOption( - this.option.outputClassNameCase, - table.tableName - ); + // 테이블 클래스 코드 생성 + private generateTableCode(table: Table) { + const tableClassName = convertNameCaseByOption( + this.option.outputClassNameCase, + table.tableName + ); - return `@Entity({ + return `@Entity({ name: '${table.tableName}', // database: '', // schema : true, @@ -76,35 +73,33 @@ export class TypeOrmEmitter implements IEmmiter { export class ${tableClassName} { ${table.columns.map((column) => this.generateColumn(column)).join("\n\n")} }`; - } + } - emit( - tables: Table[], - option: IOption = { - sourceSplit: true, - outputClassNameCase: "PASCAL", - outputFieldNameCase: "CAMEL", - } - ): Source[] { - this.option = option; + emit( + tables: Table[], + option: IOption = { + sourceSplit: true, + outputClassNameCase: "PASCAL", + outputFieldNameCase: "CAMEL", + } + ): Source[] { + this.option = option; - if (option?.sourceSplit) { - return tables.map((table) => ({ - sourceName: table.tableName, - source: importTemplate + "\n" + this.generateTableCode(table), - })); - } else { - return [ - { - sourceName: "all", - source: - importTemplate + - "\n" + - tables - .map((table) => this.generateTableCode(table)) - .join("\n\n"), - }, - ]; - } + if (option?.sourceSplit) { + return tables.map((table) => ({ + sourceName: table.tableName, + source: importTemplate + "\n" + this.generateTableCode(table), + })); + } else { + return [ + { + sourceName: "all", + source: + importTemplate + + "\n" + + tables.map((table) => this.generateTableCode(table)).join("\n\n"), + }, + ]; } + } }