You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Current behavior:
I think the bug occurs when I call the .open() function on a SQLiteDBConnection.
Expected behavior:
No error.
Steps to reproduce:
Install necessary dependencies.
Create a db connection
Open the connection
Related code:
Here is a class I use for managing the database.
import{CapacitorSQLite,SQLiteConnection,SQLiteDBConnection,DBSQLiteValues}from"@capacitor-community/sqlite";import{SqlStatements}from"../lib/sqlStatements";import{Utils}from"../lib/utils";import{AppContent}from"../lib/types";import{TABLE_BPJ_JOURNAL,TABLE_CPD,TABLE_EVENTS,TABLE_HOME_SLIDES,TABLE_MEMBER_BENEFITS,TABLE_MEMBER_DISCOUNTS,TABLE_MISC,TABLE_NEWS,TABLE_PI_JOURNAL,TABLE_POLLS,}from"../lib/constants";import{AppContentSchema}from"../lib/typeSchemas";import{PreferencesService}from"./preferencesService";constDATABASE_NAME="cop_db";constDATABASE_READ_ONLY=false;constDATABASE_LATEST_SCHEMA_VERSION=2;classLocalDatabaseService{
#sqliteConnection =newSQLiteConnection(CapacitorSQLite);asyncinitDatabase(savedDatabaseSchemaVersion: number){try{// Perform initial table creation IF the tables don't already existconstdbConnection=awaitthis.open();awaitdbConnection.execute(SqlStatements.setupTables);awaitthis.updateDatabaseSchema(dbConnection,savedDatabaseSchemaVersion);}catch(error){throwUtils.extractErrorMessage(error);}finally{awaitthis.close();}}// update database schema if requiredasyncupdateDatabaseSchema(dbConnection: SQLiteDBConnection,savedDatabaseSchemaVersion: number): Promise<void>{if(savedDatabaseSchemaVersion<DATABASE_LATEST_SCHEMA_VERSION){awaitdbConnection.execute("ALTER TABLE news_articles ADD COLUMN appExclusive INTEGER;");// add upgrade expressions here...awaitPreferencesService.saveDatabaseSchemaVersion(DATABASE_LATEST_SCHEMA_VERSION);}}asyncopen(): Promise<SQLiteDBConnection>{try{
let dbConnection: SQLiteDBConnection;constconnectionConsistency=(awaitthis.#sqliteConnection.checkConnectionsConsistency()).result;// have no idea what "connection consistency" is but the library's example souce code had it so here we areconstisConnected=(awaitthis.#sqliteConnection.isConnection(DATABASE_NAME,DATABASE_READ_ONLY)).result;// Check if already connected just in case it wasn't closed properlyif(connectionConsistency&&isConnected){console.log("retrieving existing db connection...");dbConnection=awaitthis.#sqliteConnection.retrieveConnection(DATABASE_NAME,DATABASE_READ_ONLY);}else{console.log("creating new db connection...");dbConnection=awaitthis.#sqliteConnection.createConnection(DATABASE_NAME,false,"no-encryption",1,DATABASE_READ_ONLY);}awaitdbConnection.open();returndbConnection;}catch(error){throwUtils.extractErrorMessage(error);}}asyncclose(): Promise<void>{try{constisConnected=(awaitthis.#sqliteConnection.isConnection(DATABASE_NAME,DATABASE_READ_ONLY)).result;if(isConnected){console.log("closing db connection...");awaitthis.#sqliteConnection.closeConnection(DATABASE_NAME,DATABASE_READ_ONLY);}}catch(error){throwUtils.extractErrorMessage(error);}}asyncupdateAllTables(appContent: AppContent): Promise<void>{try{constdbConnection=awaitthis.open();awaitthis.updateTable(dbConnection,TABLE_EVENTS,appContent.events);awaitthis.updateTable(dbConnection,TABLE_CPD,appContent.cpdVideos);awaitthis.updateTable(dbConnection,TABLE_HOME_SLIDES,appContent.homeCarouselSlides);awaitthis.updateTable(dbConnection,TABLE_NEWS,appContent.newsArticles);awaitthis.updateTable(dbConnection,TABLE_MEMBER_BENEFITS,appContent.memberBenefits);awaitthis.updateTable(dbConnection,TABLE_MEMBER_DISCOUNTS,appContent.memberDiscounts);awaitthis.updateTable(dbConnection,TABLE_BPJ_JOURNAL,appContent.paramedicInsightEntries);awaitthis.updateTable(dbConnection,TABLE_PI_JOURNAL,appContent.bpjEntries);awaitthis.updateTable(dbConnection,TABLE_MISC,appContent.miscellaneousItems);awaitthis.updateTable(dbConnection,TABLE_POLLS,appContent.polls);}catch(error){throwUtils.extractErrorMessage(error);}finally{awaitthis.close();}}asyncdropTables(): Promise<void>{try{constdbConnection=awaitthis.open();awaitdbConnection.query(`DROP TABLE ${TABLE_EVENTS};`);awaitdbConnection.query(`DROP TABLE ${TABLE_CPD};`);awaitdbConnection.query(`DROP TABLE ${TABLE_HOME_SLIDES};`);awaitdbConnection.query(`DROP TABLE ${TABLE_NEWS};`);awaitdbConnection.query(`DROP TABLE ${TABLE_MEMBER_BENEFITS};`);awaitdbConnection.query(`DROP TABLE ${TABLE_MEMBER_DISCOUNTS};`);awaitdbConnection.query(`DROP TABLE ${TABLE_BPJ_JOURNAL};`);awaitdbConnection.query(`DROP TABLE ${TABLE_PI_JOURNAL};`);awaitdbConnection.query(`DROP TABLE ${TABLE_MISC};`);awaitdbConnection.query(`DROP TABLE ${TABLE_POLLS};`);}catch(error){console.log("Failed to drop tables",error);}finally{awaitthis.close();}}asyncupdateTable(dbConnection: SQLiteDBConnection,tableName: string,items: any[]): Promise<void>{try{for(constitemofitems){constkeys=Object.keys(item);constvalues=Object.values(item).map((it)=>{if(it===""||it===undefined||it===null){// This value should only be set for non-boolean types (e.g. if a description field is not set in Airtable),// because all booleans are given values in the mapServerDataToCustomTypes() function.// In the local SQLite database, boolean types use INTEGER, and everything else uses TEXT, so this should be finereturn"";}if(typeofit==="object"){returnJSON.stringify(it);}returnit;});// Construct the INSERT statement dynamically based on the keys and valuesconstinsertQuery=`INSERT OR REPLACE INTO ${tableName} (${keys.join(", ")}) VALUES (${keys.map(()=>"?").join(", ")});`;awaitdbConnection.query(insertQuery,values);}// await Utils.delay(2000);// throw "custom error from updateDatabase";}catch(error){throwUtils.extractErrorMessage(error);}}asyncquery(sql: string,values: string[]): Promise<DBSQLiteValues>{try{constdbConnection=awaitthis.open();returnawaitdbConnection.query(sql,values);}catch(error){throwUtils.extractErrorMessage(error);}finally{awaitthis.close();}}asyncupdateBookmarkStatusForVideo(newValue: boolean,recordId: string): Promise<void>{try{constdbConnection=awaitthis.open();conststatement=`UPDATE ${TABLE_CPD} SET isBookmarked = ? WHERE id = ?;`;awaitdbConnection.query(statement,[newValue,recordId]);}catch(error){throwUtils.extractErrorMessage(error);}finally{awaitthis.close();}}/** * Retrieves all App Content records from the local database, checks that results are not empty, and that they are mapped to the correct types. * @returns */asyncgetAppContent(): Promise<AppContent>{try{constdbConnection=awaitthis.open();constevents=(awaitdbConnection.query(`SELECT * FROM ${TABLE_EVENTS};`,[])).values??[];constcpdVideos=(awaitdbConnection.query(`SELECT * FROM ${TABLE_CPD};`,[])).values??[];consthomeCarouselSlides=(awaitdbConnection.query(`SELECT * FROM ${TABLE_HOME_SLIDES};`,[])).values??[];constnewsArticles=(awaitdbConnection.query(`SELECT * FROM ${TABLE_NEWS};`,[])).values??[];constmemberBenefits=(awaitdbConnection.query(`SELECT * FROM ${TABLE_MEMBER_BENEFITS};`,[])).values??[];constmemberDiscounts=(awaitdbConnection.query(`SELECT * FROM ${TABLE_MEMBER_DISCOUNTS};`,[])).values??[];constparamedicInsightEntries=(awaitdbConnection.query(`SELECT * FROM ${TABLE_PI_JOURNAL};`,[])).values??[];constbpjEntries=(awaitdbConnection.query(`SELECT * FROM ${TABLE_BPJ_JOURNAL};`,[])).values??[];constmiscellaneousItems=(awaitdbConnection.query(`SELECT * FROM ${TABLE_MISC};`,[])).values??[];constpolls=(awaitdbConnection.query(`SELECT * FROM ${TABLE_POLLS};`,[])).values??[];// Parse data, converting JSON values and boolean values to the correct typesevents.forEach((e)=>{e.isRegistered=e.isRegistered===1;});cpdVideos.forEach((vid)=>{vid.presenters=JSON.parse(vid.presenters);vid.smallScreenshot=JSON.parse(vid.smallScreenshot);vid.largeScreenshot=JSON.parse(vid.largeScreenshot);vid.isBookmarked=vid.isRegistered===1;vid.isFeatured=vid.isRegistered===1;vid.isSample=vid.isRegistered===1;vid.seen=vid.seen===1;});homeCarouselSlides.forEach((slide)=>{slide.active=slide.active===1;slide.guestOnly=slide.guestOnly===1;});polls.forEach((poll)=>{poll.question=JSON.parse(poll.question);poll.responses=JSON.parse(poll.responses);poll.active=poll.active===1;});constappContent={
events,
cpdVideos,
homeCarouselSlides,
newsArticles,
memberBenefits,
memberDiscounts,
paramedicInsightEntries,
bpjEntries,
miscellaneousItems,
polls,};// Validate data against schema. Will throw an error if validation failsAppContentSchema.parse(appContent);returnappContent;}catch(error){throwUtils.extractErrorMessage(error);}finally{awaitthis.close();}}}// Export the only instance of LocalDatabaseService, acting as a 'singleton' for the app.exportdefaultnewLocalDatabaseService();
Other information:
This package was working fine on web until I recently updated Capacitor to v6.
Oops I forgot to include the error message from the console:
Uncaught (in promise) RuntimeError: memory access out of bounds
at sql-wasm.wasm:0x7d517
at f2._sqlite3_open (jeep-sqlite_dist_components_jeep-sqlite.js?v=ee19357e:4256:63)
at Sc (jeep-sqlite_dist_components_jeep-sqlite.js?v=ee19357e:3580:14)
at jeep-sqlite_dist_components_jeep-sqlite.js?v=ee19357e:4265:73
at new e2 (jeep-sqlite_dist_components_jeep-sqlite.js?v=ee19357e:2119:28)
at jeep-sqlite_dist_components_jeep-sqlite.js?v=ee19357e:6907:24
Plugin version:
6.0.2
Platform(s):
Web
Current behavior:
I think the bug occurs when I call the .open() function on a SQLiteDBConnection.
Expected behavior:
No error.
Steps to reproduce:
Related code:
Here is a class I use for managing the database.
Other information:
This package was working fine on web until I recently updated Capacitor to v6.
Capacitor doctor:
The text was updated successfully, but these errors were encountered: