mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
added table name auto generation, added onDelete support
This commit is contained in:
parent
9d924926ea
commit
bcc1c7e64b
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "typeorm",
|
||||
"private": true,
|
||||
"version": "0.0.2-alpha.3",
|
||||
"version": "0.0.2-alpha.4",
|
||||
"description": "Data-mapper ORM for Typescript",
|
||||
"license": "Apache-2.0",
|
||||
"readmeFilename": "README.md",
|
||||
|
||||
@ -5,7 +5,7 @@ import {TableMetadata} from "../../metadata-builder/metadata/TableMetadata";
|
||||
* This decorator is used to mark classes that will be a tables. Database schema will be created for all classes
|
||||
* decorated with it, and Repository can be retrieved and used for it.
|
||||
*/
|
||||
export function Table(name: string) {
|
||||
export function Table(name?: string) {
|
||||
return function (cls: Function) {
|
||||
defaultMetadataStorage.addTableMetadata(new TableMetadata(cls, name, false));
|
||||
};
|
||||
|
||||
@ -105,7 +105,12 @@ export class EntityMetadataBuilder {
|
||||
}
|
||||
|
||||
// create and add foreign key
|
||||
const foreignKey = new ForeignKeyMetadata(metadata.table, [relationalColumn], inverseSideMetadata.table, [inverseSideMetadata.primaryColumn]);
|
||||
const foreignKey = new ForeignKeyMetadata(metadata.table,
|
||||
[relationalColumn],
|
||||
inverseSideMetadata.table,
|
||||
[inverseSideMetadata.primaryColumn],
|
||||
relation.onDelete
|
||||
);
|
||||
metadata.foreignKeys.push(foreignKey);
|
||||
});
|
||||
});
|
||||
|
||||
@ -196,9 +196,6 @@ export class ColumnMetadata extends PropertyMetadata {
|
||||
this._precision = args.options.precision;
|
||||
if (args.options.collation)
|
||||
this._collation = args.options.collation;
|
||||
|
||||
if (!this._name)
|
||||
this._name = args.propertyName;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
@ -209,7 +206,10 @@ export class ColumnMetadata extends PropertyMetadata {
|
||||
* Column name in the database.
|
||||
*/
|
||||
get name(): string {
|
||||
return this.namingStrategy ? this.namingStrategy.columnName(this._name) : this._name;
|
||||
if (this._name)
|
||||
return this._name;
|
||||
|
||||
return this.namingStrategy ? this.namingStrategy.columnName(this.propertyName) : this.propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import {ColumnMetadata} from "./ColumnMetadata";
|
||||
import {TableMetadata} from "./TableMetadata";
|
||||
|
||||
export type OnDeleteType = "RESTRICT"|"CASCADE"|"SET NULL";
|
||||
|
||||
/**
|
||||
* This metadata interface contains all information foreign keys.
|
||||
*/
|
||||
@ -30,15 +32,25 @@ export class ForeignKeyMetadata {
|
||||
*/
|
||||
private _referencedColumns: ColumnMetadata[];
|
||||
|
||||
/**
|
||||
* What to do with a relation on deletion of the row containing a foreign key.
|
||||
*/
|
||||
private _onDelete: OnDeleteType;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(table: TableMetadata, columns: ColumnMetadata[], referencedTable: TableMetadata, referencedColumns: ColumnMetadata[]) {
|
||||
constructor(table: TableMetadata,
|
||||
columns: ColumnMetadata[],
|
||||
referencedTable: TableMetadata,
|
||||
referencedColumns: ColumnMetadata[],
|
||||
onDelete?: OnDeleteType) {
|
||||
this._table = table;
|
||||
this._columns = columns;
|
||||
this._referencedTable = referencedTable;
|
||||
this._referencedColumns = referencedColumns;
|
||||
this._onDelete = onDelete;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -96,4 +108,11 @@ export class ForeignKeyMetadata {
|
||||
return "fk_" + require("sha1")(key); // todo: use crypto instead?
|
||||
}
|
||||
|
||||
/**
|
||||
* Array of referenced column names.
|
||||
*/
|
||||
get onDelete(): OnDeleteType {
|
||||
return this._onDelete;
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,6 +3,7 @@ import {RelationTypes, RelationType} from "../types/RelationTypes";
|
||||
import {RelationOptions} from "../options/RelationOptions";
|
||||
import {NamingStrategy} from "../../naming-strategy/NamingStrategy";
|
||||
import {EntityMetadata} from "./EntityMetadata";
|
||||
import {OnDeleteType} from "./ForeignKeyMetadata";
|
||||
|
||||
/**
|
||||
* Function that returns a type of the field. Returned value must be a class used on the relation.
|
||||
@ -134,6 +135,11 @@ export class RelationMetadata extends PropertyMetadata {
|
||||
*/
|
||||
private _junctionEntityMetadata: EntityMetadata;
|
||||
|
||||
/**
|
||||
* What to do with a relation on deletion of the row containing a foreign key.
|
||||
*/
|
||||
private _onDelete: OnDeleteType;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
@ -157,6 +163,8 @@ export class RelationMetadata extends PropertyMetadata {
|
||||
this._oldColumnName = args.options.oldColumnName;
|
||||
if (args.options.nullable)
|
||||
this._isNullable = args.options.nullable;
|
||||
if (args.options.onDelete)
|
||||
this._onDelete = args.options.onDelete;
|
||||
|
||||
if (!this._name)
|
||||
this._name = args.propertyName;
|
||||
@ -242,6 +250,10 @@ export class RelationMetadata extends PropertyMetadata {
|
||||
return this._oldColumnName;
|
||||
}
|
||||
|
||||
get onDelete(): OnDeleteType {
|
||||
return this._onDelete;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Private Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
@ -59,7 +59,10 @@ export class TableMetadata {
|
||||
* Table name in the database.
|
||||
*/
|
||||
get name() {
|
||||
return this.namingStrategy ? this.namingStrategy.tableName(this._name) : this._name;
|
||||
if (this._name)
|
||||
return this._name;
|
||||
|
||||
return this.namingStrategy ? this.namingStrategy.tableName((<any>this._target).name) : (<any>this._target).name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import {OnDeleteType} from "../metadata/ForeignKeyMetadata";
|
||||
/**
|
||||
* Describes all relation's options.
|
||||
*/
|
||||
@ -37,6 +38,6 @@ export interface RelationOptions {
|
||||
/**
|
||||
* Database cascade action on delete.
|
||||
*/
|
||||
onDelete?: boolean;
|
||||
onDelete?: OnDeleteType;
|
||||
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
import {NamingStrategy} from "./NamingStrategy";
|
||||
import * as _ from "lodash";
|
||||
|
||||
/**
|
||||
* Naming strategy that is used by default.
|
||||
@ -6,7 +7,7 @@ import {NamingStrategy} from "./NamingStrategy";
|
||||
export class DefaultNamingStrategy implements NamingStrategy {
|
||||
|
||||
tableName(className: string): string {
|
||||
return className;
|
||||
return _.snakeCase(className);
|
||||
}
|
||||
|
||||
columnName(propertyName: string): string {
|
||||
|
||||
@ -325,7 +325,7 @@ export class EntityPersistOperationBuilder {
|
||||
|
||||
private diffColumns(metadata: EntityMetadata, newEntity: any, dbEntity: any) {
|
||||
return metadata.columns
|
||||
.filter(column => !column.isVirtual)
|
||||
.filter(column => !column.isVirtual && !column.isUpdateDate && !column.isCreateDate)
|
||||
.filter(column => newEntity[column.propertyName] !== dbEntity[column.propertyName]);
|
||||
}
|
||||
|
||||
|
||||
@ -307,10 +307,10 @@ export class QueryBuilder<Entity> {
|
||||
if (this.firstResult || this.maxResults) {
|
||||
const metadata = this.connection.getEntityMetadata(this.fromEntity.alias.target);
|
||||
let idsQuery = `SELECT DISTINCT(distinctAlias.${mainAlias}_${metadata.primaryColumn.name}) as ids`;
|
||||
if (this.orderBys)
|
||||
if (this.orderBys && this.orderBys.length > 0)
|
||||
idsQuery += ", " + this.orderBys.map(orderBy => orderBy.sort.replace(".", "_")).join(", ");
|
||||
idsQuery += ` FROM (${this.getSql()}) distinctAlias`;
|
||||
if (this.orderBys)
|
||||
if (this.orderBys && this.orderBys.length > 0)
|
||||
idsQuery += " ORDER BY " + this.orderBys.map(order => "distinctAlias." + order.sort.replace(".", "_") + " " + order.order).join(", ");
|
||||
if (this.maxResults)
|
||||
idsQuery += " LIMIT " + this.maxResults;
|
||||
@ -351,6 +351,13 @@ export class QueryBuilder<Entity> {
|
||||
.then(results => parseInt(results[0]["cnt"]));
|
||||
}
|
||||
|
||||
getResultsAndCount(): Promise<[Entity[], number]> {
|
||||
return Promise.all<any>([
|
||||
this.getResults(),
|
||||
this.getCount()
|
||||
]);
|
||||
}
|
||||
|
||||
clone(options?: { skipOrderBys?: boolean }) {
|
||||
const qb = new QueryBuilder(this.connection);
|
||||
|
||||
|
||||
@ -53,9 +53,11 @@ export class MysqlSchemaBuilder extends SchemaBuilder {
|
||||
}
|
||||
|
||||
addForeignKeyQuery(foreignKey: ForeignKeyMetadata): Promise<void> {
|
||||
const sql = `ALTER TABLE ${foreignKey.table.name} ADD CONSTRAINT \`${foreignKey.name}\` ` +
|
||||
let sql = `ALTER TABLE ${foreignKey.table.name} ADD CONSTRAINT \`${foreignKey.name}\` ` +
|
||||
`FOREIGN KEY (${foreignKey.columnNames.join(", ")}) ` +
|
||||
`REFERENCES ${foreignKey.referencedTable.name}(${foreignKey.referencedColumnNames.join(",")})`;
|
||||
if (foreignKey.onDelete)
|
||||
sql += " ON DELETE " + foreignKey.onDelete;
|
||||
return this.query(sql).then(() => {});
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user