diff --git a/src/drivers/MssqlDriver.ts b/src/drivers/MssqlDriver.ts index d28451a..c185a0a 100644 --- a/src/drivers/MssqlDriver.ts +++ b/src/drivers/MssqlDriver.ts @@ -195,6 +195,7 @@ ORDER BY }) }) + return entities; } async GetRelations(entities: EntityInfo[]): Promise { diff --git a/test/integration/examples/sample16-indexes/entity/Post.ts b/test/integration/examples/sample16-indexes/entity/Post.ts new file mode 100644 index 0000000..13a775d --- /dev/null +++ b/test/integration/examples/sample16-indexes/entity/Post.ts @@ -0,0 +1,26 @@ +import { Column, Entity, Index, PrimaryGeneratedColumn } from "typeorm" + +@Entity("Post") +@Index("my_index_with_id_and_text", ["id", "text"]) +@Index("my_index_with_id_and_title", (post: Post) => [post.id, post.title]) +export class Post { + + @PrimaryGeneratedColumn() + id: number; + + @Index() + @Column() + extra: string; + + @Column() + @Index() + title: string; + + @Column({ unique: true }) + text: string; + + @Column() + @Index() + likesCount: number; + +} \ No newline at end of file diff --git a/test/utils/EntityFileToJson.ts b/test/utils/EntityFileToJson.ts index 53daa96..07b4254 100644 --- a/test/utils/EntityFileToJson.ts +++ b/test/utils/EntityFileToJson.ts @@ -5,11 +5,11 @@ export class EntityFileToJson { if (decoratorParameters.length > 0) { if (decoratorParameters.search(',') > 0) { col.columnTypes = decoratorParameters.substring(0, decoratorParameters.indexOf(',')).trim().split('|').map(function (x) { - // if (!x.endsWith('[]')) { - // x = x + '[]'// can't distinguish OneTwoMany from OneToOne without indexes - // } - return x; - }); + // if (!x.endsWith('[]')) { + // x = x + '[]'// can't distinguish OneTwoMany from OneToOne without indexes + // } + return x; + }); let badJSON = decoratorParameters.substring(decoratorParameters.indexOf(',') + 1).trim() if (badJSON.lastIndexOf(',') == badJSON.length - 3) { badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1] @@ -33,6 +33,53 @@ export class EntityFileToJson { } } } + getIndexOptions(trimmedLine: string, ind: EntityIndex) { + let decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')')) + + if (decoratorParameters.length > 0) { + let containsTables = decoratorParameters.search('\\[') > -1 + let containsOptions = decoratorParameters.search('{') > -1 + let containsName = decoratorParameters.search('"') > -1//TODO:no name, but fields as string[] + if (containsName) { + + ind.indexName = decoratorParameters.slice(decoratorParameters.indexOf('"') + 1, decoratorParameters.substr(decoratorParameters.indexOf('"') + 1).indexOf('"')) + } + if (containsTables) { + let columnsStr = decoratorParameters.slice(decoratorParameters.indexOf('[') + 1, decoratorParameters.indexOf(']')) + ind.columnNames.push(...columnsStr.split(',').map((val) => { + let colName = '' + if (val.search('\\.') > -1) { + colName = val.split('.')[1] + } else { + colName = val.slice(val.indexOf('"') + 1, val.lastIndexOf('"')) + } + return colName + }).filter(v => { + return v.length > 0 + })) + + } + if (containsOptions) { + let optionsStr = decoratorParameters.slice(decoratorParameters.indexOf('{') + 1, decoratorParameters.indexOf('}')) + optionsStr.split(',').forEach((v) => { + if (v.split(':').length - 1 > 0) { + switch (optionsStr.split(':')[0].trim()) { + case "unique": + ind.isUnique = optionsStr.split(':')[1].trim() == 'true' ? true : false; + break; + + default: + console.log(`[EntityFileToJson:convert] Index option not recognized ${ind.indexName}:`) + console.log(`${optionsStr}`) + break; + } + } + }) + + } + + } + } convert(entityFile: Buffer): EntityJson { let retVal = new EntityJson(); @@ -67,7 +114,10 @@ export class EntityFileToJson { priorPartOfMultilineStatement = trimmedLine; continue; } else { - //TODO:Add indicies to comparision model + isMultilineStatement = false; + let ind = new EntityIndex() + this.getIndexOptions(trimmedLine, ind) + retVal.indicies.push(ind); continue; } } @@ -122,7 +172,7 @@ export class EntityFileToJson { let column = new EntityColumn() retVal.columns.push(column) column.relationType = "ManyToOne" - column.isOwnerOfRelation=true; + column.isOwnerOfRelation = true; continue; } } else if (trimmedLine.startsWith('@OneToMany')) { @@ -165,26 +215,36 @@ export class EntityFileToJson { priorPartOfMultilineStatement = trimmedLine; continue; } else { - //TODO:Add indicies to comparision model + isMultilineStatement = false; + let ind = new EntityIndex() + this.getIndexOptions(trimmedLine, ind) + retVal.indicies.push(ind); continue; } } else if (trimmedLine.split(':').length - 1 > 0) { retVal.columns[retVal.columns.length - 1].columnName = trimmedLine.split(':')[0].trim(); //TODO:Should check if null only column is nullable? retVal.columns[retVal.columns.length - 1].columnTypes = trimmedLine.split(':')[1].split(';')[0].trim().split('|').map(function (x) { - if (x=='any') { - x='string' //for json columns + if (x == 'any') { + x = 'string' //for json columns } // if (!x.endsWith('[]')) { // x = x + '[]'// can't distinguish OneTwoMany from OneToOne without indexes // } return x; }); - + if (!retVal.columns[retVal.columns.length - 1].columnTypes.some(function (this, val, ind, arr) { return val == "null" ? true : false; })) retVal.columns[retVal.columns.length - 1].columnTypes.push('null') - + if (retVal.indicies.length > 0 && retVal.indicies[retVal.indicies.length - 1].columnNames.length == 0) { + retVal.indicies[retVal.indicies.length - 1].columnNames.push(retVal.columns[retVal.columns.length - 1].columnName) + } + retVal.indicies.forEach(ind => { + if (ind.isUnique && ind.columnNames.length == 1 && ind.columnNames[0] == retVal.columns[retVal.columns.length - 1].columnName) { + retVal.columns[retVal.columns.length - 1].columnOptions['unique'] = true + } + }) continue } else if (trimmedLine = '}') { isInClassBody = false; @@ -209,11 +269,17 @@ class EntityJson { entityOptions: any = {} columns: EntityColumn[] = []; + indicies: EntityIndex[] = []; } class EntityColumn { columnName: string - columnTypes: string[] + columnTypes: string[] = [] columnOptions: any = {} relationType: "OneToOne" | "OneToMany" | "ManyToOne" | "None" = "None" isOwnerOfRelation: boolean = false; +} +class EntityIndex { + indexName: string + columnNames: string[] = [] + isUnique: boolean = false } \ No newline at end of file