UNPKG

12.8 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var Table_1 = require("../schema-builder/table/Table");
5var SqlServerDriver_1 = require("../driver/sqlserver/SqlServerDriver");
6var MssqlParameter_1 = require("../driver/sqlserver/MssqlParameter");
7var OracleDriver_1 = require("../driver/oracle/OracleDriver");
8/**
9 * Caches query result into current database, into separate table called "query-result-cache".
10 */
11var DbQueryResultCache = /** @class */ (function () {
12 // -------------------------------------------------------------------------
13 // Constructor
14 // -------------------------------------------------------------------------
15 function DbQueryResultCache(connection) {
16 this.connection = connection;
17 var options = this.connection.driver.options;
18 var cacheOptions = typeof this.connection.options.cache === "object" ? this.connection.options.cache : {};
19 var cacheTableName = cacheOptions.tableName || "query-result-cache";
20 this.queryResultCacheTable = this.connection.driver.buildTableName(cacheTableName, options.schema, options.database);
21 }
22 // -------------------------------------------------------------------------
23 // Public Methods
24 // -------------------------------------------------------------------------
25 /**
26 * Creates a connection with given cache provider.
27 */
28 DbQueryResultCache.prototype.connect = function () {
29 return tslib_1.__awaiter(this, void 0, void 0, function () {
30 return tslib_1.__generator(this, function (_a) {
31 return [2 /*return*/];
32 });
33 });
34 };
35 /**
36 * Disconnects with given cache provider.
37 */
38 DbQueryResultCache.prototype.disconnect = function () {
39 return tslib_1.__awaiter(this, void 0, void 0, function () {
40 return tslib_1.__generator(this, function (_a) {
41 return [2 /*return*/];
42 });
43 });
44 };
45 /**
46 * Creates table for storing cache if it does not exist yet.
47 */
48 DbQueryResultCache.prototype.synchronize = function (queryRunner) {
49 return tslib_1.__awaiter(this, void 0, void 0, function () {
50 var driver, tableExist;
51 return tslib_1.__generator(this, function (_a) {
52 switch (_a.label) {
53 case 0:
54 queryRunner = this.getQueryRunner(queryRunner);
55 driver = this.connection.driver;
56 return [4 /*yield*/, queryRunner.hasTable(this.queryResultCacheTable)];
57 case 1:
58 tableExist = _a.sent();
59 if (tableExist)
60 return [2 /*return*/];
61 return [4 /*yield*/, queryRunner.createTable(new Table_1.Table({
62 name: this.queryResultCacheTable,
63 columns: [
64 {
65 name: "id",
66 isPrimary: true,
67 isNullable: false,
68 type: driver.normalizeType({ type: driver.mappedDataTypes.cacheId }),
69 generationStrategy: "increment",
70 isGenerated: true
71 },
72 {
73 name: "identifier",
74 type: driver.normalizeType({ type: driver.mappedDataTypes.cacheIdentifier }),
75 isNullable: true
76 },
77 {
78 name: "time",
79 type: driver.normalizeType({ type: driver.mappedDataTypes.cacheTime }),
80 isPrimary: false,
81 isNullable: false
82 },
83 {
84 name: "duration",
85 type: driver.normalizeType({ type: driver.mappedDataTypes.cacheDuration }),
86 isPrimary: false,
87 isNullable: false
88 },
89 {
90 name: "query",
91 type: driver.normalizeType({ type: driver.mappedDataTypes.cacheQuery }),
92 isPrimary: false,
93 isNullable: false
94 },
95 {
96 name: "result",
97 type: driver.normalizeType({ type: driver.mappedDataTypes.cacheResult }),
98 isNullable: false
99 },
100 ]
101 }))];
102 case 2:
103 _a.sent();
104 return [2 /*return*/];
105 }
106 });
107 });
108 };
109 /**
110 * Caches given query result.
111 * Returns cache result if found.
112 * Returns undefined if result is not cached.
113 */
114 DbQueryResultCache.prototype.getFromCache = function (options, queryRunner) {
115 queryRunner = this.getQueryRunner(queryRunner);
116 var qb = this.connection
117 .createQueryBuilder(queryRunner)
118 .select()
119 .from(this.queryResultCacheTable, "cache");
120 if (options.identifier) {
121 return qb
122 .where(qb.escape("cache") + "." + qb.escape("identifier") + " = :identifier")
123 .setParameters({ identifier: this.connection.driver instanceof SqlServerDriver_1.SqlServerDriver ? new MssqlParameter_1.MssqlParameter(options.identifier, "nvarchar") : options.identifier })
124 .getRawOne();
125 }
126 else if (options.query) {
127 if (this.connection.driver instanceof OracleDriver_1.OracleDriver) {
128 return qb
129 .where("dbms_lob.compare(" + qb.escape("cache") + "." + qb.escape("query") + ", :query) = 0", { query: options.query })
130 .getRawOne();
131 }
132 return qb
133 .where(qb.escape("cache") + "." + qb.escape("query") + " = :query")
134 .setParameters({ query: this.connection.driver instanceof SqlServerDriver_1.SqlServerDriver ? new MssqlParameter_1.MssqlParameter(options.query, "nvarchar") : options.query })
135 .getRawOne();
136 }
137 return Promise.resolve(undefined);
138 };
139 /**
140 * Checks if cache is expired or not.
141 */
142 DbQueryResultCache.prototype.isExpired = function (savedCache) {
143 var duration = typeof savedCache.duration === "string" ? parseInt(savedCache.duration) : savedCache.duration;
144 return ((typeof savedCache.time === "string" ? parseInt(savedCache.time) : savedCache.time) + duration) < new Date().getTime();
145 };
146 /**
147 * Stores given query result in the cache.
148 */
149 DbQueryResultCache.prototype.storeInCache = function (options, savedCache, queryRunner) {
150 return tslib_1.__awaiter(this, void 0, void 0, function () {
151 var insertedValues, qb, qb;
152 return tslib_1.__generator(this, function (_a) {
153 switch (_a.label) {
154 case 0:
155 queryRunner = this.getQueryRunner(queryRunner);
156 insertedValues = options;
157 if (this.connection.driver instanceof SqlServerDriver_1.SqlServerDriver) { // todo: bad abstraction, re-implement this part, probably better if we create an entity metadata for cache table
158 insertedValues = {
159 identifier: new MssqlParameter_1.MssqlParameter(options.identifier, "nvarchar"),
160 time: new MssqlParameter_1.MssqlParameter(options.time, "bigint"),
161 duration: new MssqlParameter_1.MssqlParameter(options.duration, "int"),
162 query: new MssqlParameter_1.MssqlParameter(options.query, "nvarchar"),
163 result: new MssqlParameter_1.MssqlParameter(options.result, "nvarchar"),
164 };
165 }
166 if (!(savedCache && savedCache.identifier)) return [3 /*break*/, 2];
167 qb = queryRunner.manager
168 .createQueryBuilder()
169 .update(this.queryResultCacheTable)
170 .set(insertedValues);
171 qb.where(qb.escape("identifier") + " = :condition", { condition: insertedValues.identifier });
172 return [4 /*yield*/, qb.execute()];
173 case 1:
174 _a.sent();
175 return [3 /*break*/, 6];
176 case 2:
177 if (!(savedCache && savedCache.query)) return [3 /*break*/, 4];
178 qb = queryRunner.manager
179 .createQueryBuilder()
180 .update(this.queryResultCacheTable)
181 .set(insertedValues);
182 if (this.connection.driver instanceof OracleDriver_1.OracleDriver) {
183 qb.where("dbms_lob.compare(\"query\", :condition) = 0", { condition: insertedValues.query });
184 }
185 else {
186 qb.where(qb.escape("query") + " = :condition", { condition: insertedValues.query });
187 }
188 return [4 /*yield*/, qb.execute()];
189 case 3:
190 _a.sent();
191 return [3 /*break*/, 6];
192 case 4: // otherwise insert
193 return [4 /*yield*/, queryRunner.manager
194 .createQueryBuilder()
195 .insert()
196 .into(this.queryResultCacheTable)
197 .values(insertedValues)
198 .execute()];
199 case 5:
200 _a.sent();
201 _a.label = 6;
202 case 6: return [2 /*return*/];
203 }
204 });
205 });
206 };
207 /**
208 * Clears everything stored in the cache.
209 */
210 DbQueryResultCache.prototype.clear = function (queryRunner) {
211 return tslib_1.__awaiter(this, void 0, void 0, function () {
212 return tslib_1.__generator(this, function (_a) {
213 return [2 /*return*/, this.getQueryRunner(queryRunner).clearTable(this.queryResultCacheTable)];
214 });
215 });
216 };
217 /**
218 * Removes all cached results by given identifiers from cache.
219 */
220 DbQueryResultCache.prototype.remove = function (identifiers, queryRunner) {
221 return tslib_1.__awaiter(this, void 0, void 0, function () {
222 var _this = this;
223 return tslib_1.__generator(this, function (_a) {
224 switch (_a.label) {
225 case 0: return [4 /*yield*/, Promise.all(identifiers.map(function (identifier) {
226 var qb = _this.getQueryRunner(queryRunner).manager.createQueryBuilder();
227 return qb.delete()
228 .from(_this.queryResultCacheTable)
229 .where(qb.escape("identifier") + " = :identifier", { identifier: identifier })
230 .execute();
231 }))];
232 case 1:
233 _a.sent();
234 return [2 /*return*/];
235 }
236 });
237 });
238 };
239 // -------------------------------------------------------------------------
240 // Protected Methods
241 // -------------------------------------------------------------------------
242 /**
243 * Gets a query runner to work with.
244 */
245 DbQueryResultCache.prototype.getQueryRunner = function (queryRunner) {
246 if (queryRunner)
247 return queryRunner;
248 return this.connection.createQueryRunner("master");
249 };
250 return DbQueryResultCache;
251}());
252exports.DbQueryResultCache = DbQueryResultCache;
253
254//# sourceMappingURL=DbQueryResultCache.js.map