angular-sqlite-app-starter
angular-sqlite-app-starter copied to clipboard
Ionic/Angular SQLite Application Starter
Ionic/Angular SQLite App Starter
angular-sqlite-app-starter
Ionic/Angular application demonstrating the use of the
@capacitor-community/sqlite@web
this app uses Capacitor 4
Maintainers
Maintainer | GitHub | Social |
---|---|---|
Quéau Jean Pierre | jepiqueau |
Installation
To start building your App using this Starter App, clone this repo to a new directory:
git clone https://github.com/jepiqueau/angular-sqlite-app-starter.git
cd angular-sqlite-app-starter
git remote rm origin
- then install it
npm install
npx cap update
To run the app for developing, you can do any of these commands:
ionic serve
npm start
ionic serve --lab
To run angular test:
ng test
To build the app for testing:
npm run build
npx cap copy
To build the app for production:
npm run build-production
npx cap copy
To change the app name and app id, go to capacitor.config.ts
and change:
"appId": "com.jeep.app.ionic.angular",
"appName": "angular-sqlite-app-starter",
If you don't see the tests on android you could put the biometrics to false in capacitor.config.ts
androidBiometric.biometricAuth = false;
Building Native Project
Android
npx cap open android
Once Android Studio launches, you can build your app through the standard Android Studio workflow.
iOS
npx cap open ios
Building Web Code
🛑 Now available with @capacitor-community/sqlite@web
🛑
The @capacitor-community/sqlite@web
is now implementing sqlite for Web Browsers using a companion Stencil component jeep-sqlite
which itself is based on sql.js
for in-memory and localforage
for storing the database in an IndexedDB storage.
if you run
ionic serve
-
with
jeep-sqlite
installed:you will be able to run SQLite queries. The sqlite.service.ts has been modified to handle them. see Web Usage documentation
-
without
jeep-sqlite
installed:
Not implemented on Web
Building Electron project
cd electron
npm install
npm run build
cd ..
npx cap sync @capacitor-community/electron
npm run build
npx cap copy @capacitor-community/electron
npx cap open @capacitor-community/electron
When your Electron app is tested and you would like to create an executable either for Mac or for Windows
cd electron
npm run electron:make
Test SQLite access
The @capacitor-community/sqlite
tests are accessible through the home page.
- Test 2 Databases
- Test Existing Connection
- Test Upgrade Versions
- Test Encryption
- Test Import Json
- Test Export Json
- Test Export Json #59
- Test Copy From Assets
The application uses a service class as a wrapper to the @capacitor-community/sqlite
plugin
Resulting Output
At the end of the test, seven databases should have been created,
- testNewSQLite.db
- testSetSQLite.db encrypted password
sqlite secret
- test-updversionSQLite.db
- db-from-jsonSQLite.db
- db-from-json59SQLite.db
- dbForCopySQLite.db
- myDBSQLite.db
Angular Service
An Angular Service has been defined as a wrapper to the @capacitor-community/sqlite
plugin and from release 2.9.0-alpha.5
can be used at a singleton service
initialized in app.component.ts
and imported as a provider in app.module.ts
. In this case the DBConnection
can be used through Pages (see example in existingconnection.page.ts
which can be called after the execution of test2dbs.page.ts
).
import { Injectable } from '@angular/core';
import { Capacitor } from '@capacitor/core';
import { CapacitorSQLite, SQLiteDBConnection, SQLiteConnection, capSQLiteSet,
capSQLiteChanges, capSQLiteValues, capEchoResult, capSQLiteResult
} from '@capacitor-community/sqlite';
@Injectable()
export class SQLiteService {
sqlite: SQLiteConnection;
isService: boolean = false;
platform: string;
sqlitePlugin: any;
native: boolean = false;
constructor() {
}
/**
* Plugin Initialization
*/
initializePlugin(): Promise<boolean> {
return new Promise (resolve => {
this.platform = Capacitor.getPlatform();
if(this.platform === 'ios' || this.platform === 'android') this.native = true;
console.log("*** native " + this.native)
this.sqlitePlugin = CapacitorSQLite;
this.sqlite = new SQLiteConnection(this.sqlitePlugin);
this.isService = true;
console.log("$$$ in service this.isService " + this.isService + " $$$")
resolve(true);
});
}
/**
* Echo a value
* @param value
*/
async echo(value: string): Promise<capEchoResult> {
if(this.sqlite != null) {
try {
return await this.sqlite.echo(value);
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error("no connection open"));
}
}
async isSecretStored(): Promise<capSQLiteResult> {
if(!this.native) {
return Promise.reject(new Error(`Not implemented for ${this.platform} platform`));
}
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.isSecretStored());
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
async setEncryptionSecret(passphrase: string): Promise<void> {
if(!this.native) {
return Promise.reject(new Error(`Not implemented for ${this.platform} platform`));
}
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.setEncryptionSecret(passphrase));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
async changeEncryptionSecret(passphrase: string, oldpassphrase: string): Promise<void> {
if(!this.native) {
return Promise.reject(new Error(`Not implemented for ${this.platform} platform`));
}
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.changeEncryptionSecret(passphrase, oldpassphrase));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* addUpgradeStatement
* @param database
* @param fromVersion
* @param toVersion
* @param statement
* @param set
*/
async addUpgradeStatement(database:string, fromVersion: number,
toVersion: number, statement: string,
set?: capSQLiteSet[])
: Promise<void> {
if(this.sqlite != null) {
try {
await this.sqlite.addUpgradeStatement(database, fromVersion, toVersion,
statement, set ? set : []);
return Promise.resolve();
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open for ${database}`));
}
}
/**
* Create a connection to a database
* @param database
* @param encrypted
* @param mode
* @param version
*/
async createConnection(database:string, encrypted: boolean,
mode: string, version: number
): Promise<SQLiteDBConnection> {
if(this.sqlite != null) {
try {
const db: SQLiteDBConnection = await this.sqlite.createConnection(
database, encrypted, mode, version);
if (db != null) {
return Promise.resolve(db);
} else {
return Promise.reject(new Error(`no db returned is null`));
}
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open for ${database}`));
}
}
/**
* Close a connection to a database
* @param database
*/
async closeConnection(database:string): Promise<void> {
if(this.sqlite != null) {
try {
await this.sqlite.closeConnection(database);
return Promise.resolve();
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open for ${database}`));
}
}
/**
* Retrieve an existing connection to a database
* @param database
*/
async retrieveConnection(database:string):
Promise<SQLiteDBConnection> {
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.retrieveConnection(database));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open for ${database}`));
}
}
/**
* Retrieve all existing connections
*/
async retrieveAllConnections():
Promise<Map<string, SQLiteDBConnection>> {
if(this.sqlite != null) {
try {
const myConns = await this.sqlite.retrieveAllConnections();
/* let keys = [...myConns.keys()];
keys.forEach( (value) => {
console.log("Connection: " + value);
});
*/
return Promise.resolve(myConns);
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Close all existing connections
*/
async closeAllConnections(): Promise<void> {
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.closeAllConnections());
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Check if connection exists
* @param database
*/
async isConnection(database: string): Promise<capSQLiteResult> {
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.isConnection(database));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Check Connections Consistency
* @returns
*/
async checkConnectionsConsistency(): Promise<capSQLiteResult> {
if(this.sqlite != null) {
try {
const res = await this.sqlite.checkConnectionsConsistency();
return Promise.resolve(res);
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Check if database exists
* @param database
*/
async isDatabase(database: string): Promise<capSQLiteResult> {
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.isDatabase(database));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Get the list of databases
*/
async getDatabaseList() : Promise<capSQLiteValues> {
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.getDatabaseList());
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Add "SQLite" suffix to old database's names
*/
async addSQLiteSuffix(folderPath?: string): Promise<void>{
if(!this.native) {
return Promise.reject(new Error(`Not implemented for ${this.platform} platform`));
}
if(this.sqlite != null) {
try {
const path: string = folderPath ? folderPath : "default";
return Promise.resolve(await this.sqlite.addSQLiteSuffix(path));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Delete old databases
*/
async deleteOldDatabases(folderPath?: string): Promise<void>{
if(!this.native) {
return Promise.reject(new Error(`Not implemented for ${this.platform} platform`));
}
if(this.sqlite != null) {
try {
const path: string = folderPath ? folderPath : "default";
return Promise.resolve(await this.sqlite.deleteOldDatabases(path));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Import from a Json Object
* @param jsonstring
*/
async importFromJson(jsonstring:string): Promise<capSQLiteChanges> {
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.importFromJson(jsonstring));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Is Json Object Valid
* @param jsonstring Check the validity of a given Json Object
*/
async isJsonValid(jsonstring:string): Promise<capSQLiteResult> {
if(this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.isJsonValid(jsonstring));
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
/**
* Copy databases from public/assets/databases folder to application databases folder
*/
async copyFromAssets(): Promise<void> {
if (this.sqlite != null) {
try {
return Promise.resolve(await this.sqlite.copyFromAssets());
} catch (err) {
return Promise.reject(new Error(err));
}
} else {
return Promise.reject(new Error(`no connection open`));
}
}
}
Contributors ✨
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!