feat: Aurora Data API - Postgres Support (#5651) · typeorm/typeorm@e584297

1+

import {QueryRunnerAlreadyReleasedError} from "../../error/QueryRunnerAlreadyReleasedError";

2+

import {TransactionAlreadyStartedError} from "../../error/TransactionAlreadyStartedError";

3+

import {TransactionNotStartedError} from "../../error/TransactionNotStartedError";

4+

import {QueryRunner} from "../../query-runner/QueryRunner";

5+

import {IsolationLevel} from "../types/IsolationLevel";

6+

import {AuroraDataApiPostgresDriver} from "../postgres/PostgresDriver";

7+

import {PostgresQueryRunner} from "../postgres/PostgresQueryRunner";

8+9+

class PostgresQueryRunnerWrapper extends PostgresQueryRunner {

10+

driver: any;

11+12+

constructor(driver: any, mode: "master"|"slave") {

13+

super(driver, mode);

14+

}

15+

}

16+17+

/**

18+

* Runs queries on a single postgres database connection.

19+

*/

20+

export class AuroraDataApiPostgresQueryRunner extends PostgresQueryRunnerWrapper implements QueryRunner {

21+22+

// -------------------------------------------------------------------------

23+

// Public Implemented Properties

24+

// -------------------------------------------------------------------------

25+26+

/**

27+

* Database driver used by connection.

28+

*/

29+

driver: AuroraDataApiPostgresDriver;

30+31+

// -------------------------------------------------------------------------

32+

// Protected Properties

33+

// -------------------------------------------------------------------------

34+35+

/**

36+

* Promise used to obtain a database connection for a first time.

37+

*/

38+

protected databaseConnectionPromise: Promise<any>;

39+40+

/**

41+

* Special callback provided by a driver used to release a created connection.

42+

*/

43+

protected releaseCallback: Function;

44+45+

// -------------------------------------------------------------------------

46+

// Constructor

47+

// -------------------------------------------------------------------------

48+49+

constructor(driver: AuroraDataApiPostgresDriver, mode: "master"|"slave" = "master") {

50+

super(driver, mode);

51+

}

52+53+

// -------------------------------------------------------------------------

54+

// Public Methods

55+

// -------------------------------------------------------------------------

56+57+

/**

58+

* Creates/uses database connection from the connection pool to perform further operations.

59+

* Returns obtained database connection.

60+

*/

61+

connect(): Promise<any> {

62+

if (this.databaseConnection)

63+

return Promise.resolve(this.databaseConnection);

64+65+

if (this.databaseConnectionPromise)

66+

return this.databaseConnectionPromise;

67+68+

if (this.mode === "slave" && this.driver.isReplicated) {

69+

this.databaseConnectionPromise = this.driver.obtainSlaveConnection().then(([ connection, release]: any[]) => {

70+

this.driver.connectedQueryRunners.push(this);

71+

this.databaseConnection = connection;

72+

this.releaseCallback = release;

73+

return this.databaseConnection;

74+

});

75+76+

} else { // master

77+

this.databaseConnectionPromise = this.driver.obtainMasterConnection().then(([connection, release]: any[]) => {

78+

this.driver.connectedQueryRunners.push(this);

79+

this.databaseConnection = connection;

80+

this.releaseCallback = release;

81+

return this.databaseConnection;

82+

});

83+

}

84+85+

return this.databaseConnectionPromise;

86+

}

87+88+

/**

89+

* Starts transaction on the current connection.

90+

*/

91+

async startTransaction(isolationLevel?: IsolationLevel): Promise<void> {

92+

if (this.isTransactionActive)

93+

throw new TransactionAlreadyStartedError();

94+95+

this.isTransactionActive = true;

96+

await this.driver.client.startTransaction();

97+

}

98+99+

/**

100+

* Commits transaction.

101+

* Error will be thrown if transaction was not started.

102+

*/

103+

async commitTransaction(): Promise<void> {

104+

if (!this.isTransactionActive)

105+

throw new TransactionNotStartedError();

106+107+

await this.driver.client.commitTransaction();

108+

this.isTransactionActive = false;

109+

}

110+111+

/**

112+

* Rollbacks transaction.

113+

* Error will be thrown if transaction was not started.

114+

*/

115+

async rollbackTransaction(): Promise<void> {

116+

if (!this.isTransactionActive)

117+

throw new TransactionNotStartedError();

118+119+

await this.driver.client.rollbackTransaction();

120+

this.isTransactionActive = false;

121+

}

122+123+

/**

124+

* Executes a given SQL query.

125+

*/

126+

async query(query: string, parameters?: any[]): Promise<any> {

127+

if (this.isReleased)

128+

throw new QueryRunnerAlreadyReleasedError();

129+130+

const result = await this.driver.client.query(query, parameters);

131+132+

if (result.records) {

133+

return result.records;

134+

}

135+136+

return result;

137+

}

138+

}