typeorm 0.3.7-dev.97e1dc1 → 0.3.7-dev.a748f3c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/cache/DbQueryResultCache.d.ts +1 -1
- package/browser/cache/DbQueryResultCache.js +5 -1
- package/browser/cache/DbQueryResultCache.js.map +1 -1
- package/browser/driver/better-sqlite3/BetterSqlite3ConnectionOptions.d.ts +4 -0
- package/browser/driver/better-sqlite3/BetterSqlite3ConnectionOptions.js.map +1 -1
- package/browser/driver/better-sqlite3/BetterSqlite3Driver.d.ts +1 -1
- package/browser/driver/better-sqlite3/BetterSqlite3Driver.js +4 -3
- package/browser/driver/better-sqlite3/BetterSqlite3Driver.js.map +1 -1
- package/browser/driver/sap/SapQueryRunner.d.ts +7 -0
- package/browser/driver/sap/SapQueryRunner.js +24 -2
- package/browser/driver/sap/SapQueryRunner.js.map +1 -1
- package/cache/DbQueryResultCache.d.ts +1 -1
- package/cache/DbQueryResultCache.js +5 -1
- package/cache/DbQueryResultCache.js.map +1 -1
- package/driver/better-sqlite3/BetterSqlite3ConnectionOptions.d.ts +4 -0
- package/driver/better-sqlite3/BetterSqlite3ConnectionOptions.js.map +1 -1
- package/driver/better-sqlite3/BetterSqlite3Driver.d.ts +1 -1
- package/driver/better-sqlite3/BetterSqlite3Driver.js +6 -5
- package/driver/better-sqlite3/BetterSqlite3Driver.js.map +1 -1
- package/driver/sap/SapQueryRunner.d.ts +7 -0
- package/driver/sap/SapQueryRunner.js +24 -2
- package/driver/sap/SapQueryRunner.js.map +1 -1
- package/package.json +1 -1
|
@@ -48,5 +48,5 @@ export declare class DbQueryResultCache implements QueryResultCache {
|
|
|
48
48
|
/**
|
|
49
49
|
* Gets a query runner to work with.
|
|
50
50
|
*/
|
|
51
|
-
protected getQueryRunner(queryRunner
|
|
51
|
+
protected getQueryRunner(queryRunner?: QueryRunner): QueryRunner;
|
|
52
52
|
}
|
|
@@ -229,8 +229,9 @@ class DbQueryResultCache {
|
|
|
229
229
|
* Removes all cached results by given identifiers from cache.
|
|
230
230
|
*/
|
|
231
231
|
async remove(identifiers, queryRunner) {
|
|
232
|
+
let _queryRunner = queryRunner || this.getQueryRunner();
|
|
232
233
|
await Promise.all(identifiers.map((identifier) => {
|
|
233
|
-
const qb =
|
|
234
|
+
const qb = _queryRunner.manager.createQueryBuilder();
|
|
234
235
|
return qb
|
|
235
236
|
.delete()
|
|
236
237
|
.from(this.queryResultCacheTable)
|
|
@@ -239,6 +240,9 @@ class DbQueryResultCache {
|
|
|
239
240
|
})
|
|
240
241
|
.execute();
|
|
241
242
|
}));
|
|
243
|
+
if (!queryRunner) {
|
|
244
|
+
await _queryRunner.release();
|
|
245
|
+
}
|
|
242
246
|
}
|
|
243
247
|
// -------------------------------------------------------------------------
|
|
244
248
|
// Protected Methods
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cache/DbQueryResultCache.ts"],"names":[],"mappings":"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","file":"DbQueryResultCache.js","sourcesContent":["import { ObjectLiteral } from \"../common/ObjectLiteral\"\nimport { DataSource } from \"../data-source/DataSource\"\nimport { MssqlParameter } from \"../driver/sqlserver/MssqlParameter\"\nimport { QueryRunner } from \"../query-runner/QueryRunner\"\nimport { Table } from \"../schema-builder/table/Table\"\nimport { QueryResultCache } from \"./QueryResultCache\"\nimport { QueryResultCacheOptions } from \"./QueryResultCacheOptions\"\nimport { v4 as uuidv4 } from \"uuid\"\n\n/**\n * Caches query result into current database, into separate table called \"query-result-cache\".\n */\nexport class DbQueryResultCache implements QueryResultCache {\n // -------------------------------------------------------------------------\n // Private properties\n // -------------------------------------------------------------------------\n\n private queryResultCacheTable: string\n\n private queryResultCacheDatabase?: string\n\n private queryResultCacheSchema?: string\n\n // -------------------------------------------------------------------------\n // Constructor\n // -------------------------------------------------------------------------\n\n constructor(protected connection: DataSource) {\n const { schema } = this.connection.driver.options as any\n const database = this.connection.driver.database\n const cacheOptions =\n typeof this.connection.options.cache === \"object\"\n ? this.connection.options.cache\n : {}\n const cacheTableName = cacheOptions.tableName || \"query-result-cache\"\n\n this.queryResultCacheDatabase = database\n this.queryResultCacheSchema = schema\n this.queryResultCacheTable = this.connection.driver.buildTableName(\n cacheTableName,\n schema,\n database,\n )\n }\n\n // -------------------------------------------------------------------------\n // Public Methods\n // -------------------------------------------------------------------------\n\n /**\n * Creates a connection with given cache provider.\n */\n async connect(): Promise<void> {}\n\n /**\n * Disconnects with given cache provider.\n */\n async disconnect(): Promise<void> {}\n\n /**\n * Creates table for storing cache if it does not exist yet.\n */\n async synchronize(queryRunner?: QueryRunner): Promise<void> {\n queryRunner = this.getQueryRunner(queryRunner)\n const driver = this.connection.driver\n const tableExist = await queryRunner.hasTable(\n this.queryResultCacheTable,\n ) // todo: table name should be configurable\n if (tableExist) return\n\n await queryRunner.createTable(\n new Table({\n database: this.queryResultCacheDatabase,\n schema: this.queryResultCacheSchema,\n name: this.queryResultCacheTable,\n columns: [\n {\n name: \"id\",\n isPrimary: true,\n isNullable: false,\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheId,\n }),\n generationStrategy:\n driver.options.type === \"spanner\"\n ? \"uuid\"\n : \"increment\",\n isGenerated: true,\n },\n {\n name: \"identifier\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheIdentifier,\n }),\n isNullable: true,\n },\n {\n name: \"time\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheTime,\n }),\n isPrimary: false,\n isNullable: false,\n },\n {\n name: \"duration\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheDuration,\n }),\n isPrimary: false,\n isNullable: false,\n },\n {\n name: \"query\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheQuery,\n }),\n isPrimary: false,\n isNullable: false,\n },\n {\n name: \"result\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheResult,\n }),\n isNullable: false,\n },\n ],\n }),\n )\n }\n\n /**\n * Caches given query result.\n * Returns cache result if found.\n * Returns undefined if result is not cached.\n */\n getFromCache(\n options: QueryResultCacheOptions,\n queryRunner?: QueryRunner,\n ): Promise<QueryResultCacheOptions | undefined> {\n queryRunner = this.getQueryRunner(queryRunner)\n const qb = this.connection\n .createQueryBuilder(queryRunner)\n .select()\n .from(this.queryResultCacheTable, \"cache\")\n\n if (options.identifier) {\n return qb\n .where(\n `${qb.escape(\"cache\")}.${qb.escape(\n \"identifier\",\n )} = :identifier`,\n )\n .setParameters({\n identifier:\n this.connection.driver.options.type === \"mssql\"\n ? new MssqlParameter(options.identifier, \"nvarchar\")\n : options.identifier,\n })\n .getRawOne()\n } else if (options.query) {\n if (this.connection.driver.options.type === \"oracle\") {\n return qb\n .where(\n `dbms_lob.compare(${qb.escape(\"cache\")}.${qb.escape(\n \"query\",\n )}, :query) = 0`,\n { query: options.query },\n )\n .getRawOne()\n }\n\n return qb\n .where(`${qb.escape(\"cache\")}.${qb.escape(\"query\")} = :query`)\n .setParameters({\n query:\n this.connection.driver.options.type === \"mssql\"\n ? new MssqlParameter(options.query, \"nvarchar\")\n : options.query,\n })\n .getRawOne()\n }\n\n return Promise.resolve(undefined)\n }\n\n /**\n * Checks if cache is expired or not.\n */\n isExpired(savedCache: QueryResultCacheOptions): boolean {\n const duration =\n typeof savedCache.duration === \"string\"\n ? parseInt(savedCache.duration)\n : savedCache.duration\n return (\n (typeof savedCache.time === \"string\"\n ? parseInt(savedCache.time as any)\n : savedCache.time)! +\n duration <\n new Date().getTime()\n )\n }\n\n /**\n * Stores given query result in the cache.\n */\n async storeInCache(\n options: QueryResultCacheOptions,\n savedCache: QueryResultCacheOptions | undefined,\n queryRunner?: QueryRunner,\n ): Promise<void> {\n const shouldCreateQueryRunner =\n queryRunner === undefined ||\n queryRunner?.getReplicationMode() === \"slave\"\n\n if (queryRunner === undefined || shouldCreateQueryRunner) {\n queryRunner = this.connection.createQueryRunner(\"master\")\n }\n\n let insertedValues: ObjectLiteral = options\n if (this.connection.driver.options.type === \"mssql\") {\n // todo: bad abstraction, re-implement this part, probably better if we create an entity metadata for cache table\n insertedValues = {\n identifier: new MssqlParameter(options.identifier, \"nvarchar\"),\n time: new MssqlParameter(options.time, \"bigint\"),\n duration: new MssqlParameter(options.duration, \"int\"),\n query: new MssqlParameter(options.query, \"nvarchar\"),\n result: new MssqlParameter(options.result, \"nvarchar\"),\n }\n }\n\n if (savedCache && savedCache.identifier) {\n // if exist then update\n const qb = queryRunner.manager\n .createQueryBuilder()\n .update(this.queryResultCacheTable)\n .set(insertedValues)\n\n qb.where(`${qb.escape(\"identifier\")} = :condition`, {\n condition: insertedValues.identifier,\n })\n await qb.execute()\n } else if (savedCache && savedCache.query) {\n // if exist then update\n const qb = queryRunner.manager\n .createQueryBuilder()\n .update(this.queryResultCacheTable)\n .set(insertedValues)\n\n if (this.connection.driver.options.type === \"oracle\") {\n qb.where(`dbms_lob.compare(\"query\", :condition) = 0`, {\n condition: insertedValues.query,\n })\n } else {\n qb.where(`${qb.escape(\"query\")} = :condition`, {\n condition: insertedValues.query,\n })\n }\n\n await qb.execute()\n } else {\n // Spanner does not support auto-generated columns\n if (\n this.connection.driver.options.type === \"spanner\" &&\n !insertedValues.id\n ) {\n insertedValues.id = uuidv4()\n }\n\n // otherwise insert\n await queryRunner.manager\n .createQueryBuilder()\n .insert()\n .into(this.queryResultCacheTable)\n .values(insertedValues)\n .execute()\n }\n\n if (shouldCreateQueryRunner) {\n await queryRunner.release()\n }\n }\n\n /**\n * Clears everything stored in the cache.\n */\n async clear(queryRunner: QueryRunner): Promise<void> {\n return this.getQueryRunner(queryRunner).clearTable(\n this.queryResultCacheTable,\n )\n }\n\n /**\n * Removes all cached results by given identifiers from cache.\n */\n async remove(\n identifiers: string[],\n queryRunner?: QueryRunner,\n ): Promise<void> {\n await Promise.all(\n identifiers.map((identifier) => {\n const qb =\n this.getQueryRunner(\n queryRunner,\n ).manager.createQueryBuilder()\n return qb\n .delete()\n .from(this.queryResultCacheTable)\n .where(`${qb.escape(\"identifier\")} = :identifier`, {\n identifier,\n })\n .execute()\n }),\n )\n }\n\n // -------------------------------------------------------------------------\n // Protected Methods\n // -------------------------------------------------------------------------\n\n /**\n * Gets a query runner to work with.\n */\n protected getQueryRunner(\n queryRunner: QueryRunner | undefined,\n ): QueryRunner {\n if (queryRunner) return queryRunner\n\n return this.connection.createQueryRunner()\n }\n}\n"],"sourceRoot":".."}
|
|
1
|
+
{"version":3,"sources":["../../src/cache/DbQueryResultCache.ts"],"names":[],"mappings":"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","file":"DbQueryResultCache.js","sourcesContent":["import { ObjectLiteral } from \"../common/ObjectLiteral\"\nimport { DataSource } from \"../data-source/DataSource\"\nimport { MssqlParameter } from \"../driver/sqlserver/MssqlParameter\"\nimport { QueryRunner } from \"../query-runner/QueryRunner\"\nimport { Table } from \"../schema-builder/table/Table\"\nimport { QueryResultCache } from \"./QueryResultCache\"\nimport { QueryResultCacheOptions } from \"./QueryResultCacheOptions\"\nimport { v4 as uuidv4 } from \"uuid\"\n\n/**\n * Caches query result into current database, into separate table called \"query-result-cache\".\n */\nexport class DbQueryResultCache implements QueryResultCache {\n // -------------------------------------------------------------------------\n // Private properties\n // -------------------------------------------------------------------------\n\n private queryResultCacheTable: string\n\n private queryResultCacheDatabase?: string\n\n private queryResultCacheSchema?: string\n\n // -------------------------------------------------------------------------\n // Constructor\n // -------------------------------------------------------------------------\n\n constructor(protected connection: DataSource) {\n const { schema } = this.connection.driver.options as any\n const database = this.connection.driver.database\n const cacheOptions =\n typeof this.connection.options.cache === \"object\"\n ? this.connection.options.cache\n : {}\n const cacheTableName = cacheOptions.tableName || \"query-result-cache\"\n\n this.queryResultCacheDatabase = database\n this.queryResultCacheSchema = schema\n this.queryResultCacheTable = this.connection.driver.buildTableName(\n cacheTableName,\n schema,\n database,\n )\n }\n\n // -------------------------------------------------------------------------\n // Public Methods\n // -------------------------------------------------------------------------\n\n /**\n * Creates a connection with given cache provider.\n */\n async connect(): Promise<void> {}\n\n /**\n * Disconnects with given cache provider.\n */\n async disconnect(): Promise<void> {}\n\n /**\n * Creates table for storing cache if it does not exist yet.\n */\n async synchronize(queryRunner?: QueryRunner): Promise<void> {\n queryRunner = this.getQueryRunner(queryRunner)\n const driver = this.connection.driver\n const tableExist = await queryRunner.hasTable(\n this.queryResultCacheTable,\n ) // todo: table name should be configurable\n if (tableExist) return\n\n await queryRunner.createTable(\n new Table({\n database: this.queryResultCacheDatabase,\n schema: this.queryResultCacheSchema,\n name: this.queryResultCacheTable,\n columns: [\n {\n name: \"id\",\n isPrimary: true,\n isNullable: false,\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheId,\n }),\n generationStrategy:\n driver.options.type === \"spanner\"\n ? \"uuid\"\n : \"increment\",\n isGenerated: true,\n },\n {\n name: \"identifier\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheIdentifier,\n }),\n isNullable: true,\n },\n {\n name: \"time\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheTime,\n }),\n isPrimary: false,\n isNullable: false,\n },\n {\n name: \"duration\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheDuration,\n }),\n isPrimary: false,\n isNullable: false,\n },\n {\n name: \"query\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheQuery,\n }),\n isPrimary: false,\n isNullable: false,\n },\n {\n name: \"result\",\n type: driver.normalizeType({\n type: driver.mappedDataTypes.cacheResult,\n }),\n isNullable: false,\n },\n ],\n }),\n )\n }\n\n /**\n * Caches given query result.\n * Returns cache result if found.\n * Returns undefined if result is not cached.\n */\n getFromCache(\n options: QueryResultCacheOptions,\n queryRunner?: QueryRunner,\n ): Promise<QueryResultCacheOptions | undefined> {\n queryRunner = this.getQueryRunner(queryRunner)\n const qb = this.connection\n .createQueryBuilder(queryRunner)\n .select()\n .from(this.queryResultCacheTable, \"cache\")\n\n if (options.identifier) {\n return qb\n .where(\n `${qb.escape(\"cache\")}.${qb.escape(\n \"identifier\",\n )} = :identifier`,\n )\n .setParameters({\n identifier:\n this.connection.driver.options.type === \"mssql\"\n ? new MssqlParameter(options.identifier, \"nvarchar\")\n : options.identifier,\n })\n .getRawOne()\n } else if (options.query) {\n if (this.connection.driver.options.type === \"oracle\") {\n return qb\n .where(\n `dbms_lob.compare(${qb.escape(\"cache\")}.${qb.escape(\n \"query\",\n )}, :query) = 0`,\n { query: options.query },\n )\n .getRawOne()\n }\n\n return qb\n .where(`${qb.escape(\"cache\")}.${qb.escape(\"query\")} = :query`)\n .setParameters({\n query:\n this.connection.driver.options.type === \"mssql\"\n ? new MssqlParameter(options.query, \"nvarchar\")\n : options.query,\n })\n .getRawOne()\n }\n\n return Promise.resolve(undefined)\n }\n\n /**\n * Checks if cache is expired or not.\n */\n isExpired(savedCache: QueryResultCacheOptions): boolean {\n const duration =\n typeof savedCache.duration === \"string\"\n ? parseInt(savedCache.duration)\n : savedCache.duration\n return (\n (typeof savedCache.time === \"string\"\n ? parseInt(savedCache.time as any)\n : savedCache.time)! +\n duration <\n new Date().getTime()\n )\n }\n\n /**\n * Stores given query result in the cache.\n */\n async storeInCache(\n options: QueryResultCacheOptions,\n savedCache: QueryResultCacheOptions | undefined,\n queryRunner?: QueryRunner,\n ): Promise<void> {\n const shouldCreateQueryRunner =\n queryRunner === undefined ||\n queryRunner?.getReplicationMode() === \"slave\"\n\n if (queryRunner === undefined || shouldCreateQueryRunner) {\n queryRunner = this.connection.createQueryRunner(\"master\")\n }\n\n let insertedValues: ObjectLiteral = options\n if (this.connection.driver.options.type === \"mssql\") {\n // todo: bad abstraction, re-implement this part, probably better if we create an entity metadata for cache table\n insertedValues = {\n identifier: new MssqlParameter(options.identifier, \"nvarchar\"),\n time: new MssqlParameter(options.time, \"bigint\"),\n duration: new MssqlParameter(options.duration, \"int\"),\n query: new MssqlParameter(options.query, \"nvarchar\"),\n result: new MssqlParameter(options.result, \"nvarchar\"),\n }\n }\n\n if (savedCache && savedCache.identifier) {\n // if exist then update\n const qb = queryRunner.manager\n .createQueryBuilder()\n .update(this.queryResultCacheTable)\n .set(insertedValues)\n\n qb.where(`${qb.escape(\"identifier\")} = :condition`, {\n condition: insertedValues.identifier,\n })\n await qb.execute()\n } else if (savedCache && savedCache.query) {\n // if exist then update\n const qb = queryRunner.manager\n .createQueryBuilder()\n .update(this.queryResultCacheTable)\n .set(insertedValues)\n\n if (this.connection.driver.options.type === \"oracle\") {\n qb.where(`dbms_lob.compare(\"query\", :condition) = 0`, {\n condition: insertedValues.query,\n })\n } else {\n qb.where(`${qb.escape(\"query\")} = :condition`, {\n condition: insertedValues.query,\n })\n }\n\n await qb.execute()\n } else {\n // Spanner does not support auto-generated columns\n if (\n this.connection.driver.options.type === \"spanner\" &&\n !insertedValues.id\n ) {\n insertedValues.id = uuidv4()\n }\n\n // otherwise insert\n await queryRunner.manager\n .createQueryBuilder()\n .insert()\n .into(this.queryResultCacheTable)\n .values(insertedValues)\n .execute()\n }\n\n if (shouldCreateQueryRunner) {\n await queryRunner.release()\n }\n }\n\n /**\n * Clears everything stored in the cache.\n */\n async clear(queryRunner: QueryRunner): Promise<void> {\n return this.getQueryRunner(queryRunner).clearTable(\n this.queryResultCacheTable,\n )\n }\n\n /**\n * Removes all cached results by given identifiers from cache.\n */\n async remove(\n identifiers: string[],\n queryRunner?: QueryRunner,\n ): Promise<void> {\n let _queryRunner: QueryRunner = queryRunner || this.getQueryRunner()\n await Promise.all(\n identifiers.map((identifier) => {\n const qb = _queryRunner.manager.createQueryBuilder()\n return qb\n .delete()\n .from(this.queryResultCacheTable)\n .where(`${qb.escape(\"identifier\")} = :identifier`, {\n identifier,\n })\n .execute()\n }),\n )\n\n if (!queryRunner) {\n await _queryRunner.release()\n }\n }\n\n // -------------------------------------------------------------------------\n // Protected Methods\n // -------------------------------------------------------------------------\n\n /**\n * Gets a query runner to work with.\n */\n protected getQueryRunner(queryRunner?: QueryRunner): QueryRunner {\n if (queryRunner) return queryRunner\n\n return this.connection.createQueryRunner()\n }\n}\n"],"sourceRoot":".."}
|
|
@@ -52,4 +52,8 @@ export interface BetterSqlite3ConnectionOptions extends BaseDataSourceOptions {
|
|
|
52
52
|
* Provide a function that gets called with every SQL string executed by the database connection.
|
|
53
53
|
*/
|
|
54
54
|
readonly verbose?: Function;
|
|
55
|
+
/**
|
|
56
|
+
* Relative or absolute path to the native addon (better_sqlite3.node).
|
|
57
|
+
*/
|
|
58
|
+
readonly nativeBinding?: string;
|
|
55
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/driver/better-sqlite3/BetterSqlite3ConnectionOptions.ts"],"names":[],"mappings":"","file":"BetterSqlite3ConnectionOptions.js","sourcesContent":["import { BaseDataSourceOptions } from \"../../data-source/BaseDataSourceOptions\"\n\n/**\n * Sqlite-specific connection options.\n */\nexport interface BetterSqlite3ConnectionOptions extends BaseDataSourceOptions {\n /**\n * Database type.\n */\n readonly type: \"better-sqlite3\"\n\n /**\n * Storage type or path to the storage.\n */\n readonly database: string\n\n /**\n * The driver object\n * This defaults to require(\"better-sqlite3\")\n */\n readonly driver?: any\n\n /**\n * Encryption key for for SQLCipher.\n */\n readonly key?: string\n\n /**\n * Cache size of sqlite statement to speed up queries.\n * Default: 100.\n */\n readonly statementCacheSize?: number\n\n /**\n * Function to run before a database is used in typeorm.\n * You can set pragmas, register plugins or register\n * functions or aggregates in this function.\n */\n readonly prepareDatabase?: (db: any) => void | Promise<void>\n\n /**\n * Open the database connection in readonly mode.\n * Default: false.\n */\n readonly readonly?: boolean\n\n /**\n * If the database does not exist, an Error will be thrown instead of creating a new file.\n * This option does not affect in-memory or readonly database connections.\n * Default: false.\n */\n readonly fileMustExist?: boolean\n\n /**\n * The number of milliseconds to wait when executing queries\n * on a locked database, before throwing a SQLITE_BUSY error.\n * Default: 5000.\n */\n readonly timeout?: number\n\n /**\n * Provide a function that gets called with every SQL string executed by the database connection.\n */\n readonly verbose?: Function\n}\n"],"sourceRoot":"../.."}
|
|
1
|
+
{"version":3,"sources":["../../src/driver/better-sqlite3/BetterSqlite3ConnectionOptions.ts"],"names":[],"mappings":"","file":"BetterSqlite3ConnectionOptions.js","sourcesContent":["import { BaseDataSourceOptions } from \"../../data-source/BaseDataSourceOptions\"\n\n/**\n * Sqlite-specific connection options.\n */\nexport interface BetterSqlite3ConnectionOptions extends BaseDataSourceOptions {\n /**\n * Database type.\n */\n readonly type: \"better-sqlite3\"\n\n /**\n * Storage type or path to the storage.\n */\n readonly database: string\n\n /**\n * The driver object\n * This defaults to require(\"better-sqlite3\")\n */\n readonly driver?: any\n\n /**\n * Encryption key for for SQLCipher.\n */\n readonly key?: string\n\n /**\n * Cache size of sqlite statement to speed up queries.\n * Default: 100.\n */\n readonly statementCacheSize?: number\n\n /**\n * Function to run before a database is used in typeorm.\n * You can set pragmas, register plugins or register\n * functions or aggregates in this function.\n */\n readonly prepareDatabase?: (db: any) => void | Promise<void>\n\n /**\n * Open the database connection in readonly mode.\n * Default: false.\n */\n readonly readonly?: boolean\n\n /**\n * If the database does not exist, an Error will be thrown instead of creating a new file.\n * This option does not affect in-memory or readonly database connections.\n * Default: false.\n */\n readonly fileMustExist?: boolean\n\n /**\n * The number of milliseconds to wait when executing queries\n * on a locked database, before throwing a SQLITE_BUSY error.\n * Default: 5000.\n */\n readonly timeout?: number\n\n /**\n * Provide a function that gets called with every SQL string executed by the database connection.\n */\n readonly verbose?: Function\n\n /**\n * Relative or absolute path to the native addon (better_sqlite3.node).\n */\n readonly nativeBinding?: string\n}\n"],"sourceRoot":"../.."}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DataSource } from "../../data-source
|
|
1
|
+
import { DataSource } from "../../data-source";
|
|
2
2
|
import { ColumnType } from "../types/ColumnTypes";
|
|
3
3
|
import { QueryRunner } from "../../query-runner/QueryRunner";
|
|
4
4
|
import { AbstractSqliteDriver } from "../sqlite-abstract/AbstractSqliteDriver";
|
|
@@ -4,8 +4,8 @@ exports.BetterSqlite3Driver = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const mkdirp_1 = tslib_1.__importDefault(require("mkdirp"));
|
|
6
6
|
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const error_1 = require("../../error");
|
|
8
|
+
const error_2 = require("../../error");
|
|
9
9
|
const PlatformTools_1 = require("../../platform/PlatformTools");
|
|
10
10
|
const AbstractSqliteDriver_1 = require("../sqlite-abstract/AbstractSqliteDriver");
|
|
11
11
|
const BetterSqlite3QueryRunner_1 = require("./BetterSqlite3QueryRunner");
|
|
@@ -24,7 +24,7 @@ class BetterSqlite3Driver extends AbstractSqliteDriver_1.AbstractSqliteDriver {
|
|
|
24
24
|
this.database = this.options.database;
|
|
25
25
|
// validate options to make sure everything is set
|
|
26
26
|
if (!this.options.database)
|
|
27
|
-
throw new
|
|
27
|
+
throw new error_2.DriverOptionNotSetError("database");
|
|
28
28
|
// load sqlite package
|
|
29
29
|
this.loadDependencies();
|
|
30
30
|
}
|
|
@@ -88,12 +88,13 @@ class BetterSqlite3Driver extends AbstractSqliteDriver_1.AbstractSqliteDriver {
|
|
|
88
88
|
// not to create database directory if is in memory
|
|
89
89
|
if (this.options.database !== ":memory:")
|
|
90
90
|
await this.createDatabaseDirectory(path_1.default.dirname(this.options.database));
|
|
91
|
-
const { database, readonly = false, fileMustExist = false, timeout = 5000, verbose = null, prepareDatabase, } = this.options;
|
|
91
|
+
const { database, readonly = false, fileMustExist = false, timeout = 5000, verbose = null, nativeBinding = null, prepareDatabase, } = this.options;
|
|
92
92
|
const databaseConnection = this.sqlite(database, {
|
|
93
93
|
readonly,
|
|
94
94
|
fileMustExist,
|
|
95
95
|
timeout,
|
|
96
96
|
verbose,
|
|
97
|
+
nativeBinding,
|
|
97
98
|
});
|
|
98
99
|
// in the options, if encryption key for SQLCipher is setted.
|
|
99
100
|
// Must invoke key pragma before trying to do any other interaction with the database.
|
|
@@ -120,7 +121,7 @@ class BetterSqlite3Driver extends AbstractSqliteDriver_1.AbstractSqliteDriver {
|
|
|
120
121
|
this.sqlite = sqlite;
|
|
121
122
|
}
|
|
122
123
|
catch (e) {
|
|
123
|
-
throw new
|
|
124
|
+
throw new error_1.DriverPackageNotInstalledError("SQLite", "better-sqlite3");
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/driver/better-sqlite3/BetterSqlite3Driver.ts"],"names":[],"mappings":"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","file":"BetterSqlite3Driver.js","sourcesContent":["import mkdirp from \"mkdirp\"\nimport path from \"path\"\nimport { DriverPackageNotInstalledError } from \"../../error/DriverPackageNotInstalledError\"\nimport { DriverOptionNotSetError } from \"../../error/DriverOptionNotSetError\"\nimport { PlatformTools } from \"../../platform/PlatformTools\"\nimport { DataSource } from \"../../data-source/DataSource\"\nimport { ColumnType } from \"../types/ColumnTypes\"\nimport { QueryRunner } from \"../../query-runner/QueryRunner\"\nimport { AbstractSqliteDriver } from \"../sqlite-abstract/AbstractSqliteDriver\"\nimport { BetterSqlite3ConnectionOptions } from \"./BetterSqlite3ConnectionOptions\"\nimport { BetterSqlite3QueryRunner } from \"./BetterSqlite3QueryRunner\"\nimport { ReplicationMode } from \"../types/ReplicationMode\"\nimport { filepathToName, isAbsolute } from \"../../util/PathUtils\"\n\n/**\n * Organizes communication with sqlite DBMS.\n */\nexport class BetterSqlite3Driver extends AbstractSqliteDriver {\n // -------------------------------------------------------------------------\n // Public Implemented Properties\n // -------------------------------------------------------------------------\n\n /**\n * Connection options.\n */\n options: BetterSqlite3ConnectionOptions\n\n /**\n * SQLite underlying library.\n */\n sqlite: any\n\n // -------------------------------------------------------------------------\n // Constructor\n // -------------------------------------------------------------------------\n\n constructor(connection: DataSource) {\n super(connection)\n\n this.connection = connection\n this.options = connection.options as BetterSqlite3ConnectionOptions\n this.database = this.options.database\n\n // validate options to make sure everything is set\n if (!this.options.database)\n throw new DriverOptionNotSetError(\"database\")\n\n // load sqlite package\n this.loadDependencies()\n }\n\n // -------------------------------------------------------------------------\n // Public Methods\n // -------------------------------------------------------------------------\n\n /**\n * Closes connection with database.\n */\n async disconnect(): Promise<void> {\n this.queryRunner = undefined\n this.databaseConnection.close()\n }\n\n /**\n * Creates a query runner used to execute database queries.\n */\n createQueryRunner(mode: ReplicationMode): QueryRunner {\n if (!this.queryRunner)\n this.queryRunner = new BetterSqlite3QueryRunner(this)\n\n return this.queryRunner\n }\n\n normalizeType(column: {\n type?: ColumnType\n length?: number | string\n precision?: number | null\n scale?: number\n }): string {\n if ((column.type as any) === Buffer) {\n return \"blob\"\n }\n\n return super.normalizeType(column)\n }\n\n async afterConnect(): Promise<void> {\n return this.attachDatabases()\n }\n\n /**\n * For SQLite, the database may be added in the decorator metadata. It will be a filepath to a database file.\n */\n buildTableName(\n tableName: string,\n _schema?: string,\n database?: string,\n ): string {\n if (!database) return tableName\n if (this.getAttachedDatabaseHandleByRelativePath(database))\n return `${this.getAttachedDatabaseHandleByRelativePath(\n database,\n )}.${tableName}`\n\n if (database === this.options.database) return tableName\n\n // we use the decorated name as supplied when deriving attach handle (ideally without non-portable absolute path)\n const identifierHash = filepathToName(database)\n // decorated name will be assumed relative to main database file when non absolute. Paths supplied as absolute won't be portable\n const absFilepath = isAbsolute(database)\n ? database\n : path.join(this.getMainDatabasePath(), database)\n\n this.attachedDatabases[database] = {\n attachFilepathAbsolute: absFilepath,\n attachFilepathRelative: database,\n attachHandle: identifierHash,\n }\n\n return `${identifierHash}.${tableName}`\n }\n\n // -------------------------------------------------------------------------\n // Protected Methods\n // -------------------------------------------------------------------------\n\n /**\n * Creates connection with the database.\n */\n protected async createDatabaseConnection() {\n // not to create database directory if is in memory\n if (this.options.database !== \":memory:\")\n await this.createDatabaseDirectory(\n path.dirname(this.options.database),\n )\n\n const {\n database,\n readonly = false,\n fileMustExist = false,\n timeout = 5000,\n verbose = null,\n prepareDatabase,\n } = this.options\n const databaseConnection = this.sqlite(database, {\n readonly,\n fileMustExist,\n timeout,\n verbose,\n })\n // in the options, if encryption key for SQLCipher is setted.\n // Must invoke key pragma before trying to do any other interaction with the database.\n if (this.options.key) {\n databaseConnection.exec(\n `PRAGMA key = ${JSON.stringify(this.options.key)}`,\n )\n }\n\n // function to run before a database is used in typeorm.\n if (typeof prepareDatabase === \"function\") {\n prepareDatabase(databaseConnection)\n }\n\n // we need to enable foreign keys in sqlite to make sure all foreign key related features\n // working properly. this also makes onDelete to work with sqlite.\n databaseConnection.exec(`PRAGMA foreign_keys = ON`)\n\n // turn on WAL mode to enhance performance\n databaseConnection.exec(`PRAGMA journal_mode = WAL`)\n\n return databaseConnection\n }\n\n /**\n * If driver dependency is not given explicitly, then try to load it via \"require\".\n */\n protected loadDependencies(): void {\n try {\n const sqlite =\n this.options.driver || PlatformTools.load(\"better-sqlite3\")\n this.sqlite = sqlite\n } catch (e) {\n throw new DriverPackageNotInstalledError(\"SQLite\", \"better-sqlite3\")\n }\n }\n\n /**\n * Auto creates database directory if it does not exist.\n */\n protected async createDatabaseDirectory(dbPath: string): Promise<void> {\n await mkdirp(dbPath)\n }\n\n /**\n * Performs the attaching of the database files. The attachedDatabase should have been populated during calls to #buildTableName\n * during EntityMetadata production (see EntityMetadata#buildTablePath)\n *\n * https://sqlite.org/lang_attach.html\n */\n protected async attachDatabases() {\n // @todo - possibly check number of databases (but unqueriable at runtime sadly) - https://www.sqlite.org/limits.html#max_attached\n for await (const {\n attachHandle,\n attachFilepathAbsolute,\n } of Object.values(this.attachedDatabases)) {\n await this.createDatabaseDirectory(\n path.dirname(attachFilepathAbsolute),\n )\n await this.connection.query(\n `ATTACH \"${attachFilepathAbsolute}\" AS \"${attachHandle}\"`,\n )\n }\n }\n\n protected getMainDatabasePath(): string {\n const optionsDb = this.options.database\n return path.dirname(\n isAbsolute(optionsDb)\n ? optionsDb\n : path.join(this.options.baseDirectory!, optionsDb),\n )\n }\n}\n"],"sourceRoot":"../.."}
|
|
1
|
+
{"version":3,"sources":["../../src/driver/better-sqlite3/BetterSqlite3Driver.ts"],"names":[],"mappings":"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","file":"BetterSqlite3Driver.js","sourcesContent":["import mkdirp from \"mkdirp\"\nimport path from \"path\"\nimport { DriverPackageNotInstalledError } from \"../../error\"\nimport { DriverOptionNotSetError } from \"../../error\"\nimport { PlatformTools } from \"../../platform/PlatformTools\"\nimport { DataSource } from \"../../data-source\"\nimport { ColumnType } from \"../types/ColumnTypes\"\nimport { QueryRunner } from \"../../query-runner/QueryRunner\"\nimport { AbstractSqliteDriver } from \"../sqlite-abstract/AbstractSqliteDriver\"\nimport { BetterSqlite3ConnectionOptions } from \"./BetterSqlite3ConnectionOptions\"\nimport { BetterSqlite3QueryRunner } from \"./BetterSqlite3QueryRunner\"\nimport { ReplicationMode } from \"../types/ReplicationMode\"\nimport { filepathToName, isAbsolute } from \"../../util/PathUtils\"\n\n/**\n * Organizes communication with sqlite DBMS.\n */\nexport class BetterSqlite3Driver extends AbstractSqliteDriver {\n // -------------------------------------------------------------------------\n // Public Implemented Properties\n // -------------------------------------------------------------------------\n\n /**\n * Connection options.\n */\n options: BetterSqlite3ConnectionOptions\n\n /**\n * SQLite underlying library.\n */\n sqlite: any\n\n // -------------------------------------------------------------------------\n // Constructor\n // -------------------------------------------------------------------------\n\n constructor(connection: DataSource) {\n super(connection)\n\n this.connection = connection\n this.options = connection.options as BetterSqlite3ConnectionOptions\n this.database = this.options.database\n\n // validate options to make sure everything is set\n if (!this.options.database)\n throw new DriverOptionNotSetError(\"database\")\n\n // load sqlite package\n this.loadDependencies()\n }\n\n // -------------------------------------------------------------------------\n // Public Methods\n // -------------------------------------------------------------------------\n\n /**\n * Closes connection with database.\n */\n async disconnect(): Promise<void> {\n this.queryRunner = undefined\n this.databaseConnection.close()\n }\n\n /**\n * Creates a query runner used to execute database queries.\n */\n createQueryRunner(mode: ReplicationMode): QueryRunner {\n if (!this.queryRunner)\n this.queryRunner = new BetterSqlite3QueryRunner(this)\n\n return this.queryRunner\n }\n\n normalizeType(column: {\n type?: ColumnType\n length?: number | string\n precision?: number | null\n scale?: number\n }): string {\n if ((column.type as any) === Buffer) {\n return \"blob\"\n }\n\n return super.normalizeType(column)\n }\n\n async afterConnect(): Promise<void> {\n return this.attachDatabases()\n }\n\n /**\n * For SQLite, the database may be added in the decorator metadata. It will be a filepath to a database file.\n */\n buildTableName(\n tableName: string,\n _schema?: string,\n database?: string,\n ): string {\n if (!database) return tableName\n if (this.getAttachedDatabaseHandleByRelativePath(database))\n return `${this.getAttachedDatabaseHandleByRelativePath(\n database,\n )}.${tableName}`\n\n if (database === this.options.database) return tableName\n\n // we use the decorated name as supplied when deriving attach handle (ideally without non-portable absolute path)\n const identifierHash = filepathToName(database)\n // decorated name will be assumed relative to main database file when non absolute. Paths supplied as absolute won't be portable\n const absFilepath = isAbsolute(database)\n ? database\n : path.join(this.getMainDatabasePath(), database)\n\n this.attachedDatabases[database] = {\n attachFilepathAbsolute: absFilepath,\n attachFilepathRelative: database,\n attachHandle: identifierHash,\n }\n\n return `${identifierHash}.${tableName}`\n }\n\n // -------------------------------------------------------------------------\n // Protected Methods\n // -------------------------------------------------------------------------\n\n /**\n * Creates connection with the database.\n */\n protected async createDatabaseConnection() {\n // not to create database directory if is in memory\n if (this.options.database !== \":memory:\")\n await this.createDatabaseDirectory(\n path.dirname(this.options.database),\n )\n\n const {\n database,\n readonly = false,\n fileMustExist = false,\n timeout = 5000,\n verbose = null,\n nativeBinding = null,\n prepareDatabase,\n } = this.options\n const databaseConnection = this.sqlite(database, {\n readonly,\n fileMustExist,\n timeout,\n verbose,\n nativeBinding,\n })\n // in the options, if encryption key for SQLCipher is setted.\n // Must invoke key pragma before trying to do any other interaction with the database.\n if (this.options.key) {\n databaseConnection.exec(\n `PRAGMA key = ${JSON.stringify(this.options.key)}`,\n )\n }\n\n // function to run before a database is used in typeorm.\n if (typeof prepareDatabase === \"function\") {\n prepareDatabase(databaseConnection)\n }\n\n // we need to enable foreign keys in sqlite to make sure all foreign key related features\n // working properly. this also makes onDelete to work with sqlite.\n databaseConnection.exec(`PRAGMA foreign_keys = ON`)\n\n // turn on WAL mode to enhance performance\n databaseConnection.exec(`PRAGMA journal_mode = WAL`)\n\n return databaseConnection\n }\n\n /**\n * If driver dependency is not given explicitly, then try to load it via \"require\".\n */\n protected loadDependencies(): void {\n try {\n const sqlite =\n this.options.driver || PlatformTools.load(\"better-sqlite3\")\n this.sqlite = sqlite\n } catch (e) {\n throw new DriverPackageNotInstalledError(\"SQLite\", \"better-sqlite3\")\n }\n }\n\n /**\n * Auto creates database directory if it does not exist.\n */\n protected async createDatabaseDirectory(dbPath: string): Promise<void> {\n await mkdirp(dbPath)\n }\n\n /**\n * Performs the attaching of the database files. The attachedDatabase should have been populated during calls to #buildTableName\n * during EntityMetadata production (see EntityMetadata#buildTablePath)\n *\n * https://sqlite.org/lang_attach.html\n */\n protected async attachDatabases() {\n // @todo - possibly check number of databases (but unqueriable at runtime sadly) - https://www.sqlite.org/limits.html#max_attached\n for await (const {\n attachHandle,\n attachFilepathAbsolute,\n } of Object.values(this.attachedDatabases)) {\n await this.createDatabaseDirectory(\n path.dirname(attachFilepathAbsolute),\n )\n await this.connection.query(\n `ATTACH \"${attachFilepathAbsolute}\" AS \"${attachHandle}\"`,\n )\n }\n }\n\n protected getMainDatabasePath(): string {\n const optionsDb = this.options.database\n return path.dirname(\n isAbsolute(optionsDb)\n ? optionsDb\n : path.join(this.options.baseDirectory!, optionsDb),\n )\n }\n}\n"],"sourceRoot":"../.."}
|
|
@@ -52,6 +52,13 @@ export declare class SapQueryRunner extends BaseQueryRunner implements QueryRunn
|
|
|
52
52
|
* Error will be thrown if transaction was not started.
|
|
53
53
|
*/
|
|
54
54
|
rollbackTransaction(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* @description Switches on/off AUTOCOMMIT mode
|
|
57
|
+
* @link https://help.sap.com/docs/HANA_SERVICE_CF/7c78579ce9b14a669c1f3295b0d8ca16/d538d11053bd4f3f847ec5ce817a3d4c.html?locale=en-US
|
|
58
|
+
*/
|
|
59
|
+
setAutoCommit(options: {
|
|
60
|
+
status: "on" | "off";
|
|
61
|
+
}): Promise<void>;
|
|
55
62
|
/**
|
|
56
63
|
* Executes a given SQL query.
|
|
57
64
|
*/
|
|
@@ -20,6 +20,7 @@ const QueryResult_1 = require("../../query-runner/QueryResult");
|
|
|
20
20
|
const QueryLock_1 = require("../../query-runner/QueryLock");
|
|
21
21
|
const MetadataTableType_1 = require("../types/MetadataTableType");
|
|
22
22
|
const InstanceChecker_1 = require("../../util/InstanceChecker");
|
|
23
|
+
const util_1 = require("util");
|
|
23
24
|
/**
|
|
24
25
|
* Runs queries on a single SQL Server database connection.
|
|
25
26
|
*/
|
|
@@ -70,6 +71,11 @@ class SapQueryRunner extends BaseQueryRunner_1.BaseQueryRunner {
|
|
|
70
71
|
throw new TransactionAlreadyStartedError_1.TransactionAlreadyStartedError();
|
|
71
72
|
await this.broadcaster.broadcast("BeforeTransactionStart");
|
|
72
73
|
this.isTransactionActive = true;
|
|
74
|
+
/**
|
|
75
|
+
* Disable AUTOCOMMIT while running transaction.
|
|
76
|
+
* Otherwise, COMMIT/ROLLBACK doesn't work in autocommit mode.
|
|
77
|
+
*/
|
|
78
|
+
await this.setAutoCommit({ status: "off" });
|
|
73
79
|
if (isolationLevel) {
|
|
74
80
|
await this.query(`SET TRANSACTION ISOLATION LEVEL ${isolationLevel || ""}`);
|
|
75
81
|
}
|
|
@@ -87,6 +93,7 @@ class SapQueryRunner extends BaseQueryRunner_1.BaseQueryRunner {
|
|
|
87
93
|
await this.broadcaster.broadcast("BeforeTransactionCommit");
|
|
88
94
|
await this.query("COMMIT");
|
|
89
95
|
this.isTransactionActive = false;
|
|
96
|
+
await this.setAutoCommit({ status: "on" });
|
|
90
97
|
await this.broadcaster.broadcast("AfterTransactionCommit");
|
|
91
98
|
}
|
|
92
99
|
/**
|
|
@@ -101,8 +108,25 @@ class SapQueryRunner extends BaseQueryRunner_1.BaseQueryRunner {
|
|
|
101
108
|
await this.broadcaster.broadcast("BeforeTransactionRollback");
|
|
102
109
|
await this.query("ROLLBACK");
|
|
103
110
|
this.isTransactionActive = false;
|
|
111
|
+
await this.setAutoCommit({ status: "on" });
|
|
104
112
|
await this.broadcaster.broadcast("AfterTransactionRollback");
|
|
105
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* @description Switches on/off AUTOCOMMIT mode
|
|
116
|
+
* @link https://help.sap.com/docs/HANA_SERVICE_CF/7c78579ce9b14a669c1f3295b0d8ca16/d538d11053bd4f3f847ec5ce817a3d4c.html?locale=en-US
|
|
117
|
+
*/
|
|
118
|
+
async setAutoCommit(options) {
|
|
119
|
+
const connection = await this.connect();
|
|
120
|
+
const execute = (0, util_1.promisify)(connection.exec.bind(connection));
|
|
121
|
+
connection.setAutoCommit(options.status === "on");
|
|
122
|
+
const query = `SET TRANSACTION AUTOCOMMIT DDL ${options.status.toUpperCase()};`;
|
|
123
|
+
try {
|
|
124
|
+
await execute(query);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
throw new error_1.QueryFailedError(query, [], error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
106
130
|
/**
|
|
107
131
|
* Executes a given SQL query.
|
|
108
132
|
*/
|
|
@@ -114,8 +138,6 @@ class SapQueryRunner extends BaseQueryRunner_1.BaseQueryRunner {
|
|
|
114
138
|
const result = new QueryResult_1.QueryResult();
|
|
115
139
|
try {
|
|
116
140
|
const databaseConnection = await this.connect();
|
|
117
|
-
// we disable autocommit because ROLLBACK does not work in autocommit mode
|
|
118
|
-
databaseConnection.setAutoCommit(!this.isTransactionActive);
|
|
119
141
|
this.driver.connection.logger.logQuery(query, parameters, this);
|
|
120
142
|
const queryStartTime = +new Date();
|
|
121
143
|
const isInsertQuery = query.substr(0, 11) === "INSERT INTO";
|