mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
feat: added Capacitor driver (#7695)
* added new driver for Capacitor * updated CHANGELOG.md
This commit is contained in:
parent
620aac9e0f
commit
0f7a778398
@ -1,3 +1,11 @@
|
||||
## 0.2.33 (UNRELEASED)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
### Features
|
||||
|
||||
* added capacitor driver ([#7695](https://github.com/typeorm/typeorm/pull/7695))
|
||||
|
||||
## [0.2.32](https://github.com/typeorm/typeorm/compare/0.2.31...0.2.32) (2021-03-30)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
* [`postgres` / `cockroachdb` connection options](#postgres--cockroachdb-connection-options)
|
||||
* [`sqlite` connection options](#sqlite-connection-options)
|
||||
* [`better-sqlite3` connection options](#better-sqlite3-connection-options)
|
||||
* [`capacitor` connection options](#capacitor-connection-options)
|
||||
* [`cordova` connection options](#cordova-connection-options)
|
||||
* [`react-native` connection options](#react-native-connection-options)
|
||||
* [`nativescript` connection options](#nativescript-connection-options)
|
||||
@ -23,8 +24,8 @@ Connection options is a connection configuration you pass to `createConnection`
|
||||
## Common connection options
|
||||
|
||||
* `type` - Database type. You must specify what database engine you use.
|
||||
Possible values are "mysql", "postgres", "cockroachdb", "mariadb", "sqlite", "better-sqlite3", "cordova", "nativescript",
|
||||
"oracle", "mssql", "mongodb", "sqljs", "react-native".
|
||||
Possible values are "mysql", "postgres", "cockroachdb", "mariadb", "sqlite", "better-sqlite3", "capacitor", "cordova",
|
||||
"nativescript", "oracle", "mssql", "mongodb", "sqljs", "react-native".
|
||||
This option is **required**.
|
||||
|
||||
* `name` - Connection name. You'll use it to get connection you need using `getConnection(name: string)`
|
||||
@ -196,6 +197,12 @@ See [SSL options](https://github.com/mysqljs/mysql#ssl-options).
|
||||
|
||||
* `prepareDatabase` - Function to run before a database is used in typeorm. You can access original better-sqlite3 Database object here.
|
||||
|
||||
## `capacitor` connection options
|
||||
|
||||
* `database` - Database name (capacitor-sqlite will add the suffix `SQLite.db`)
|
||||
|
||||
* `driver` - The capacitor-sqlite instance. For example, `new SQLiteConnection(CapacitorSQLite)`.
|
||||
|
||||
## `cordova` connection options
|
||||
|
||||
* `database` - Database name
|
||||
|
||||
@ -14,6 +14,7 @@ import {AuroraDataApiConnectionOptions} from "../driver/aurora-data-api/AuroraDa
|
||||
import {SapConnectionOptions} from "../driver/sap/SapConnectionOptions";
|
||||
import {AuroraDataApiPostgresConnectionOptions} from "../driver/aurora-data-api-pg/AuroraDataApiPostgresConnectionOptions";
|
||||
import {BetterSqlite3ConnectionOptions} from "../driver/better-sqlite3/BetterSqlite3ConnectionOptions";
|
||||
import {CapacitorConnectionOptions} from "../driver/capacitor/CapacitorConnectionOptions";
|
||||
|
||||
|
||||
/**
|
||||
@ -37,4 +38,5 @@ export type ConnectionOptions =
|
||||
AuroraDataApiConnectionOptions|
|
||||
AuroraDataApiPostgresConnectionOptions|
|
||||
ExpoConnectionOptions|
|
||||
BetterSqlite3ConnectionOptions;
|
||||
BetterSqlite3ConnectionOptions |
|
||||
CapacitorConnectionOptions;
|
||||
|
||||
@ -17,6 +17,7 @@ import {Driver} from "./Driver";
|
||||
import {Connection} from "../connection/Connection";
|
||||
import {SapDriver} from "./sap/SapDriver";
|
||||
import {BetterSqlite3Driver} from "./better-sqlite3/BetterSqlite3Driver";
|
||||
import {CapacitorDriver} from "./capacitor/CapacitorDriver";
|
||||
|
||||
/**
|
||||
* Helps to create drivers.
|
||||
@ -63,6 +64,8 @@ export class DriverFactory {
|
||||
return new AuroraDataApiDriver(connection);
|
||||
case "aurora-data-api-pg":
|
||||
return new AuroraDataApiPostgresDriver(connection);
|
||||
case "capacitor":
|
||||
return new CapacitorDriver(connection);
|
||||
default:
|
||||
throw new MissingDriverError(type);
|
||||
}
|
||||
|
||||
21
src/driver/capacitor/CapacitorConnectionOptions.ts
Normal file
21
src/driver/capacitor/CapacitorConnectionOptions.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { BaseConnectionOptions } from "../../connection/BaseConnectionOptions";
|
||||
|
||||
/**
|
||||
* Sqlite-specific connection options.
|
||||
*/
|
||||
export interface CapacitorConnectionOptions extends BaseConnectionOptions {
|
||||
/**
|
||||
* Database type.
|
||||
*/
|
||||
readonly type: "capacitor";
|
||||
|
||||
/**
|
||||
* Database name (capacitor-sqlite will add the suffix `SQLite.db`)
|
||||
*/
|
||||
readonly database: string;
|
||||
|
||||
/**
|
||||
* The capacitor-sqlite instance. For example, `new SQLiteConnection(CapacitorSQLite)`.
|
||||
*/
|
||||
readonly driver: any;
|
||||
}
|
||||
99
src/driver/capacitor/CapacitorDriver.ts
Normal file
99
src/driver/capacitor/CapacitorDriver.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import { AbstractSqliteDriver } from "../sqlite-abstract/AbstractSqliteDriver";
|
||||
import { CapacitorConnectionOptions } from "./CapacitorConnectionOptions";
|
||||
import { CapacitorQueryRunner } from "./CapacitorQueryRunner";
|
||||
import { QueryRunner } from "../../query-runner/QueryRunner";
|
||||
import { Connection } from "../../connection/Connection";
|
||||
import {
|
||||
DriverOptionNotSetError,
|
||||
DriverPackageNotInstalledError,
|
||||
} from "../../error";
|
||||
import { ReplicationMode } from "../types/ReplicationMode";
|
||||
|
||||
export class CapacitorDriver extends AbstractSqliteDriver {
|
||||
driver: any;
|
||||
options: CapacitorConnectionOptions;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(connection: Connection) {
|
||||
super(connection);
|
||||
|
||||
this.database = this.options.database;
|
||||
this.driver = this.options.driver;
|
||||
|
||||
// validate options to make sure everything is set
|
||||
if (!this.options.database)
|
||||
throw new DriverOptionNotSetError("database");
|
||||
|
||||
if (!this.options.driver) throw new DriverOptionNotSetError("driver");
|
||||
|
||||
// load sqlite package
|
||||
this.sqlite = this.options.driver;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Public Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Performs connection to the database.
|
||||
*/
|
||||
async connect(): Promise<void> {
|
||||
this.databaseConnection = this.createDatabaseConnection();
|
||||
await this.databaseConnection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes connection with database.
|
||||
*/
|
||||
async disconnect(): Promise<void> {
|
||||
this.queryRunner = undefined;
|
||||
const databaseConnection = await this.databaseConnection;
|
||||
return databaseConnection.close().then(() => {
|
||||
this.databaseConnection = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a query runner used to execute database queries.
|
||||
*/
|
||||
createQueryRunner(mode: ReplicationMode): QueryRunner {
|
||||
if (!this.queryRunner)
|
||||
this.queryRunner = new CapacitorQueryRunner(this);
|
||||
|
||||
return this.queryRunner;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Creates connection with the database.
|
||||
*/
|
||||
protected async createDatabaseConnection() {
|
||||
const connection = await this.sqlite.createConnection(
|
||||
this.options.database,
|
||||
false,
|
||||
"no-encryption",
|
||||
1
|
||||
);
|
||||
await connection.open();
|
||||
// we need to enable foreign keys in sqlite to make sure all foreign key related features
|
||||
// working properly. this also makes onDelete to work with sqlite.
|
||||
await connection.execute(`PRAGMA foreign_keys = ON;`);
|
||||
return connection;
|
||||
}
|
||||
|
||||
protected loadDependencies(): void {
|
||||
this.sqlite = this.driver;
|
||||
if (!this.driver) {
|
||||
throw new DriverPackageNotInstalledError(
|
||||
"Capacitor",
|
||||
"@capacitor-community/sqlite"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
98
src/driver/capacitor/CapacitorQueryRunner.ts
Normal file
98
src/driver/capacitor/CapacitorQueryRunner.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { QueryRunnerAlreadyReleasedError } from "../../error/QueryRunnerAlreadyReleasedError";
|
||||
import { QueryFailedError } from "../../error/QueryFailedError";
|
||||
import { AbstractSqliteQueryRunner } from "../sqlite-abstract/AbstractSqliteQueryRunner";
|
||||
import { CapacitorDriver } from "./CapacitorDriver";
|
||||
import { Broadcaster } from "../../subscriber/Broadcaster";
|
||||
import { ObjectLiteral } from "../..";
|
||||
|
||||
/**
|
||||
* Runs queries on a single sqlite database connection.
|
||||
*/
|
||||
export class CapacitorQueryRunner extends AbstractSqliteQueryRunner {
|
||||
/**
|
||||
* Database driver used by connection.
|
||||
*/
|
||||
driver: CapacitorDriver;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Constructor
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
constructor(driver: CapacitorDriver) {
|
||||
super();
|
||||
this.driver = driver;
|
||||
this.connection = driver.connection;
|
||||
this.broadcaster = new Broadcaster(this);
|
||||
}
|
||||
|
||||
async executeSet(set: { statement: string; values?: any[] }[]) {
|
||||
if (this.isReleased) throw new QueryRunnerAlreadyReleasedError();
|
||||
|
||||
const databaseConnection = await this.connect();
|
||||
|
||||
return databaseConnection.executeSet(set, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a given SQL query.
|
||||
*/
|
||||
async query(query: string, parameters?: any[]): Promise<any> {
|
||||
if (this.isReleased) throw new QueryRunnerAlreadyReleasedError();
|
||||
|
||||
const databaseConnection = await this.connect();
|
||||
|
||||
this.driver.connection.logger.logQuery(query, parameters, this);
|
||||
|
||||
let pResult: Promise<any>;
|
||||
const command = query.substr(0, query.indexOf(" "));
|
||||
|
||||
if (
|
||||
[
|
||||
"PRAGMA",
|
||||
"BEGIN",
|
||||
"ROLLBACK",
|
||||
"COMMIT",
|
||||
"CREATE",
|
||||
"ALTER",
|
||||
"DROP",
|
||||
].indexOf(command) !== -1
|
||||
) {
|
||||
pResult = databaseConnection.execute(query, false);
|
||||
} else if (["INSERT", "UPDATE", "DELETE"].indexOf(command) !== -1) {
|
||||
pResult = databaseConnection
|
||||
.run(query, parameters, false)
|
||||
.then(
|
||||
({
|
||||
changes,
|
||||
}: {
|
||||
changes: { changes?: number; lastId?: number };
|
||||
}) => changes.lastId || changes.changes
|
||||
);
|
||||
} else {
|
||||
pResult = databaseConnection
|
||||
.query(query, parameters)
|
||||
.then(({ values }: { values: any[] }) => values);
|
||||
}
|
||||
|
||||
return pResult.catch((err: any) => {
|
||||
this.driver.connection.logger.logQueryError(
|
||||
err,
|
||||
query,
|
||||
parameters,
|
||||
this
|
||||
);
|
||||
throw new QueryFailedError(query, parameters, err);
|
||||
});
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Protected Methods
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Parametrizes given object of values. Used to create column=value queries.
|
||||
*/
|
||||
protected parametrize(objectLiteral: ObjectLiteral): string[] {
|
||||
return Object.keys(objectLiteral).map((key) => `"${key}"` + "=?");
|
||||
}
|
||||
}
|
||||
@ -18,4 +18,5 @@ export type DatabaseType =
|
||||
"aurora-data-api"|
|
||||
"aurora-data-api-pg"|
|
||||
"expo"|
|
||||
"better-sqlite3";
|
||||
"better-sqlite3" |
|
||||
"capacitor";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user