mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
refactored driver part
This commit is contained in:
parent
3ffe430eaf
commit
7aa02a5e8d
@ -24,6 +24,7 @@ export class Connection {
|
||||
private _subscribers: OrmSubscriber<any>[] = [];
|
||||
private _broadcasters: OrmBroadcaster<any>[] = [];
|
||||
private _repositories: Repository<any>[] = [];
|
||||
private _options: ConnectionOptions;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
@ -81,6 +82,13 @@ export class Connection {
|
||||
return this._repositories;
|
||||
}
|
||||
|
||||
/**
|
||||
* This connection options and settings.
|
||||
*/
|
||||
get options(): ConnectionOptions {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
@ -90,6 +98,7 @@ export class Connection {
|
||||
*/
|
||||
connect(options: ConnectionOptions): Promise<void> {
|
||||
const schemaCreator = new SchemaCreator(this);
|
||||
this._options = options;
|
||||
return this._driver
|
||||
.connect(options)
|
||||
.then(() => {
|
||||
|
||||
@ -38,4 +38,31 @@ export interface ConnectionOptions {
|
||||
*/
|
||||
autoSchemaCreate?: boolean;
|
||||
|
||||
/**
|
||||
* Logging options.
|
||||
*/
|
||||
logging?: {
|
||||
|
||||
/**
|
||||
* Some specific logger to be used. By default it console.
|
||||
*/
|
||||
logger?: (message: any, level: string) => void;
|
||||
|
||||
/**
|
||||
* Used if you want to log every executed query.
|
||||
*/
|
||||
logQueries?: boolean;
|
||||
|
||||
/**
|
||||
* Used if you want to log only failed query.
|
||||
*/
|
||||
logOnlyFailedQueries?: boolean;
|
||||
|
||||
/**
|
||||
* Used if you want to log error of the failed query.
|
||||
*/
|
||||
logFailedQueryError?: boolean;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
58
src/driver/BaseDriver.ts
Normal file
58
src/driver/BaseDriver.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import {Connection} from "../connection/Connection";
|
||||
|
||||
/**
|
||||
* Provides base functionality for all driver implementations.
|
||||
*/
|
||||
export abstract class BaseDriver {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
connection: Connection;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
protected logQuery(query: string) {
|
||||
if (this.connection.options.logging && this.connection.options.logging.logQueries)
|
||||
this.log("executing query: " + query, "log");
|
||||
}
|
||||
|
||||
protected logQueryError(error: any) {
|
||||
if (this.connection.options.logging && this.connection.options.logging.logFailedQueryError) {
|
||||
this.log("error during executing query:", "error");
|
||||
this.log(error, "error");
|
||||
}
|
||||
}
|
||||
|
||||
protected logFailedQuery(query: string) {
|
||||
if (this.connection.options.logging &&
|
||||
(this.connection.options.logging.logQueries || this.connection.options.logging.logOnlyFailedQueries))
|
||||
this.log("query failed: " + query, "error");
|
||||
}
|
||||
|
||||
protected log(message: any, level: "log"|"debug"|"info"|"error") {
|
||||
if (!this.connection.options.logging) return;
|
||||
if ( this.connection.options.logging.logger) {
|
||||
this.connection.options.logging.logger(message, level);
|
||||
} else {
|
||||
switch (level) {
|
||||
case "log":
|
||||
console.log(message);
|
||||
break;
|
||||
case "debug":
|
||||
console.debug(message);
|
||||
break;
|
||||
case "info":
|
||||
console.info(message);
|
||||
break;
|
||||
case "error":
|
||||
console.error(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,16 +13,16 @@ export interface Driver {
|
||||
*/
|
||||
native: any;
|
||||
|
||||
/**
|
||||
* Gets database name to which this connection is made.
|
||||
*/
|
||||
db: string;
|
||||
|
||||
/**
|
||||
* Connection used in this driver.
|
||||
*/
|
||||
connection: Connection;
|
||||
|
||||
/**
|
||||
* Database name to which this connection is made.
|
||||
*/
|
||||
db: string;
|
||||
|
||||
/**
|
||||
* Creates a query builder which can be used to build an sql queries.
|
||||
*/
|
||||
@ -44,27 +44,27 @@ export interface Driver {
|
||||
disconnect(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Executes a given SQL query.
|
||||
* Executes a given SQL query and returns raw database results.
|
||||
*/
|
||||
query<T>(query: string): Promise<T>;
|
||||
|
||||
/**
|
||||
* Clears all tables in the currently connected database.
|
||||
* Removes all tables from the currently connected database.
|
||||
*/
|
||||
clearDatabase(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Updates rows that match given conditions in the given table.
|
||||
* Updates rows that match given simple conditions in the given table.
|
||||
*/
|
||||
update(tableName: string, valuesMap: Object, conditions: Object): Promise<void>;
|
||||
|
||||
/**
|
||||
* Insert a new row into given table.
|
||||
* Inserts a new row into given table.
|
||||
*/
|
||||
insert(tableName: string, valuesMap: Object): Promise<any>;
|
||||
|
||||
/**
|
||||
* Insert a new row into given table.
|
||||
* Performs a simple DELETE query by a given conditions in a given table.
|
||||
*/
|
||||
delete(tableName: string, conditions: Object): Promise<void>;
|
||||
|
||||
|
||||
@ -4,32 +4,53 @@ import {SchemaBuilder} from "../schema-builder/SchemaBuilder";
|
||||
import {QueryBuilder} from "../query-builder/QueryBuilder";
|
||||
import {MysqlSchemaBuilder} from "../schema-builder/MysqlSchemaBuilder";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {ConnectionIsNotSetError} from "./error/ConnectionIsNotSetError";
|
||||
import {BaseDriver} from "./BaseDriver";
|
||||
|
||||
/**
|
||||
* This driver organizes work with mysql database.
|
||||
*/
|
||||
export class MysqlDriver implements Driver {
|
||||
export class MysqlDriver extends BaseDriver implements Driver {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Properties
|
||||
// Public Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Connection used in this driver.
|
||||
*/
|
||||
connection: Connection;
|
||||
|
||||
private mysql: any;
|
||||
private mysqlConnection: any;
|
||||
private connectionOptions: ConnectionOptions;
|
||||
// -------------------------------------------------------------------------
|
||||
// Private Properties
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Mysql library.
|
||||
*/
|
||||
private mysql: any;
|
||||
|
||||
/**
|
||||
* Connection to mysql database.
|
||||
*/
|
||||
private mysqlConnection: any;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Getter Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Access to the native implementation of the database.
|
||||
*/
|
||||
get native(): any {
|
||||
return this.mysql;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Database name to which this connection is made.
|
||||
*/
|
||||
get db(): string {
|
||||
return this.connectionOptions.database;
|
||||
return this.connection.options.database;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -37,6 +58,7 @@ export class MysqlDriver implements Driver {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(mysql: any) {
|
||||
super();
|
||||
this.mysql = mysql;
|
||||
}
|
||||
|
||||
@ -62,14 +84,15 @@ export class MysqlDriver implements Driver {
|
||||
* Performs connection to the database based on given connection options.
|
||||
*/
|
||||
connect(options: ConnectionOptions): Promise<void> {
|
||||
this.connectionOptions = options;
|
||||
this.mysqlConnection = this.mysql.createConnection({
|
||||
host: options.host,
|
||||
user: options.username,
|
||||
password: options.password,
|
||||
database: options.database
|
||||
});
|
||||
return new Promise<void>((ok, fail) => this.mysqlConnection.connect((err: any) => err ? fail(err) : ok()));
|
||||
return new Promise<void>((ok, fail) => {
|
||||
this.mysqlConnection.connect((err: any) => err ? fail(err) : ok());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +100,7 @@ export class MysqlDriver implements Driver {
|
||||
*/
|
||||
disconnect(): Promise<void> {
|
||||
if (!this.mysqlConnection)
|
||||
throw new Error("Connection is not established, cannot disconnect.");
|
||||
throw new ConnectionIsNotSetError("mysql");
|
||||
|
||||
return new Promise<void>((ok, fail) => {
|
||||
this.mysqlConnection.end((err: any) => err ? fail(err) : ok());
|
||||
@ -88,15 +111,18 @@ export class MysqlDriver implements Driver {
|
||||
* Executes a given SQL query.
|
||||
*/
|
||||
query<T>(query: string): Promise<T> {
|
||||
if (!this.mysqlConnection) throw new Error("Connection is not established, cannot execute a query.");
|
||||
// console.info("executing:", query);
|
||||
if (!this.mysqlConnection)
|
||||
throw new ConnectionIsNotSetError("mysql");
|
||||
|
||||
this.logQuery(query);
|
||||
return new Promise<any>((ok, fail) => this.mysqlConnection.query(query, (err: any, result: any) => {
|
||||
if (err) {
|
||||
console.error("query failed: ", query);
|
||||
this.logFailedQuery(query);
|
||||
this.logQueryError(err);
|
||||
fail(err);
|
||||
return;
|
||||
} else {
|
||||
ok(result);
|
||||
}
|
||||
ok(result);
|
||||
}));
|
||||
}
|
||||
|
||||
@ -104,21 +130,18 @@ export class MysqlDriver implements Driver {
|
||||
* Clears all tables in the currently connected database.
|
||||
*/
|
||||
clearDatabase(): Promise<void> {
|
||||
if (!this.mysqlConnection) throw new Error("Connection is not established, cannot execute a query.");
|
||||
if (!this.mysqlConnection)
|
||||
throw new ConnectionIsNotSetError("mysql");
|
||||
|
||||
// todo: optrize and make coder better
|
||||
|
||||
const query1 = `SET FOREIGN_KEY_CHECKS = 0;`;
|
||||
const query2 = `SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') AS q FROM information_schema.tables WHERE table_schema = '${this.connectionOptions.database}';`;
|
||||
const query3 = `SET FOREIGN_KEY_CHECKS = 1;`;
|
||||
const disableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 0;`;
|
||||
const dropTablesQuery = `SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') AS q FROM ` +
|
||||
`information_schema.tables WHERE table_schema = '${this.db}';`;
|
||||
const enableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 1;`;
|
||||
|
||||
return this.query(query1)
|
||||
.then(() => this.query<any[]>(query2))
|
||||
.then(results => {
|
||||
const dropQueries = results.map(q => this.query(q['q']));
|
||||
return Promise.all(dropQueries);
|
||||
})
|
||||
.then(() => this.query(query3))
|
||||
return this.query(disableForeignKeysCheckQuery)
|
||||
.then(() => this.query<any[]>(dropTablesQuery))
|
||||
.then(results => Promise.all(results.map(q => this.query(q['q']))))
|
||||
.then(() => this.query(enableForeignKeysCheckQuery))
|
||||
.then(() => {});
|
||||
}
|
||||
|
||||
@ -126,6 +149,9 @@ export class MysqlDriver implements Driver {
|
||||
* Updates rows that match given conditions in the given table.
|
||||
*/
|
||||
update(tableName: string, valuesMap: Object, conditions: Object): Promise<void> {
|
||||
if (!this.mysqlConnection)
|
||||
throw new ConnectionIsNotSetError("mysql");
|
||||
|
||||
const qb = this.createQueryBuilder().update(tableName, valuesMap).from(tableName, "t");
|
||||
Object.keys(conditions).forEach(key => qb.andWhere(key + "=:" + key, { [key]: (<any> conditions)[key] }));
|
||||
return qb.execute().then(() => {});
|
||||
@ -135,6 +161,9 @@ export class MysqlDriver implements Driver {
|
||||
* Insert a new row into given table.
|
||||
*/
|
||||
insert(tableName: string, keyValues: Object): Promise<any> {
|
||||
if (!this.mysqlConnection)
|
||||
throw new ConnectionIsNotSetError("mysql");
|
||||
|
||||
const columns = Object.keys(keyValues).join(",");
|
||||
const values = Object.keys(keyValues).map(key => (<any> keyValues)[key]).join(",");
|
||||
const query = `INSERT INTO ${tableName}(${columns}) VALUES (${values})`;
|
||||
@ -145,6 +174,9 @@ export class MysqlDriver implements Driver {
|
||||
* Deletes from the given table by a given conditions.
|
||||
*/
|
||||
delete(tableName: string, conditions: Object): Promise<void> {
|
||||
if (!this.mysqlConnection)
|
||||
throw new ConnectionIsNotSetError("mysql");
|
||||
|
||||
const qb = this.createQueryBuilder().delete(tableName);
|
||||
Object.keys(conditions).forEach(key => qb.andWhere(key + "=:" + key, { [key]: (<any> conditions)[key] }));
|
||||
return qb.execute().then(() => {});
|
||||
|
||||
9
src/driver/error/ConnectionIsNotSetError.ts
Normal file
9
src/driver/error/ConnectionIsNotSetError.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export class ConnectionIsNotSetError extends Error {
|
||||
name = "ConnectionIsNotSetError";
|
||||
|
||||
constructor(dbType: string) {
|
||||
super();
|
||||
this.message = `Connection with ${dbType} database is not established. Check connection configuration.`;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user