-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added Capacitor driver (#7695)
* added new driver for Capacitor * updated CHANGELOG.md
- Loading branch information
Showing
8 changed files
with
243 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}"` + "=?"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters