Skip to content

Commit

Permalink
Add SQLite commands, cause repo clear if downloading and user selects…
Browse files Browse the repository at this point in the history
… delete
  • Loading branch information
LocalNewsTV committed Jan 9, 2025
1 parent 80a77cf commit 3a35fb3
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 5 deletions.
7 changes: 6 additions & 1 deletion app/src/state/actions/userSettings/RecordSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ class RecordSet {
async (spec: { setId: string }, thunkAPI) => {
const state = thunkAPI.getState() as RootState;
const { recordSets } = state.UserSettings;
if (MOBILE && recordSets[spec.setId].cacheMetadata.status == UserRecordCacheStatus.CACHED) {
if (
MOBILE &&
[UserRecordCacheStatus.CACHED, UserRecordCacheStatus.DOWNLOADING].includes(
recordSets[spec.setId]?.cacheMetadata?.status
)
) {
const deletionResult = await thunkAPI.dispatch(RecordCache.deleteCache(spec));
if (RecordCache.deleteCache.rejected.match(deletionResult)) {
throw Error('Cache failed to delete');
Expand Down
4 changes: 3 additions & 1 deletion app/src/utils/record-cache/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { RecordSetType, UserRecordCacheStatus } from 'interfaces/UserRecordSet';
import { GeoJSONSourceSpecification } from 'maplibre-gl';
import { getCurrentJWT } from 'state/sagas/auth/auth';
import { getSelectColumnsByRecordSetType } from 'state/sagas/map/dataAccess';
import { RepositoryBoundingBoxSpec, RepositoryStatus } from 'utils/tile-cache';
import { RepositoryBoundingBoxSpec } from 'utils/tile-cache';

export enum IappRecordMode {
Record = 'record',
Expand Down Expand Up @@ -132,6 +132,7 @@ abstract class RecordCacheService {
await this.saveIapp(spec.idsToCache[i].toString(), iappRecord, tableRow);
if (i % this.RECORDS_BETWEEN_PROGRESS_UPDATES === 0 || i === spec.idsToCache.length - 1) {
abort = await this.checkForAbort(spec.setId);
console.log(abort ? 'WE ABORTED' : 'WE ARE STILL ROLLING');
/*
ProgressCallback Logic
*/
Expand All @@ -157,6 +158,7 @@ abstract class RecordCacheService {
});
await this.saveActivity(spec.idsToCache[i], await rez.json());
if (i % this.RECORDS_BETWEEN_PROGRESS_UPDATES === 0 || i === spec.idsToCache.length - 1) {
console.log(abort ? 'WE ABORTED' : 'WE ARE STILL ROLLING');
abort = await this.checkForAbort(spec.setId);
/*
ProgressCallback Logic
Expand Down
148 changes: 145 additions & 3 deletions app/src/utils/record-cache/sqlite-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { Feature } from '@turf/helpers';
import IappRecord from 'interfaces/IappRecord';
import IappTableRow from 'interfaces/IappTableRecord';
import UserRecord from 'interfaces/UserRecord';
import { RecordSetType } from 'interfaces/UserRecordSet';
import { RecordSetType, UserRecordCacheStatus } from 'interfaces/UserRecordSet';
import { GeoJSONSourceSpecification } from 'maplibre-gl';
import { IappRecordMode, RecordCacheService, RecordSetSourceMetadata } from 'utils/record-cache/index';
import {
IappRecordMode,
RecordCacheAddSpec,
RecordCacheService,
RecordSetSourceMetadata
} from 'utils/record-cache/index';
import { sqlite } from 'utils/sharedSQLiteInstance';

const CACHE_DB_NAME = 'record_cache.db';
Expand Down Expand Up @@ -46,6 +51,15 @@ const RECORD_CACHE_DB_MIGRATIONS_3 = [
GEOJSON TEXT NOT NULL
);`
];

const RECORD_CACHE_DB_MIGRATIONS_4 = [
`ALTER TABLE CACHE_METADATA
ADD COLUMN CACHE_TIME TEXT NOT NULL;`,
`ALTER TABLE CACHE_METADATA
ADD COLUMN STATUS TEXT NOT NULL;`,
`ALTER TABLE CACHE_METADATA
ADD COLUMN DATA TEXT NOT NULL;`
];
class SQLiteRecordCacheService extends RecordCacheService {
private static _instance: SQLiteRecordCacheService;

Expand All @@ -63,6 +77,129 @@ class SQLiteRecordCacheService extends RecordCacheService {
return SQLiteRecordCacheService._instance;
}

async addOrUpdateRepository(spec: RecordCacheAddSpec): Promise<void> {
if (this.cacheDB == null) {
throw new Error(CACHE_UNAVAILABLE);
}
try {
await this.cacheDB.query(
//language=SQLite`
`INSERT INTO CACHE_METADATA(SET_ID, STATUS, CACHE_TIME, DATA)
VALUES(?, ?, ?, ?)
ON CONFLICT(SET_ID)
DO UPDATE SET
STATUS = excluded.STATUS,
CACHE_TIME = excluded.CACHE_TIME,
DATA = excluded.DATA`,
[spec.setId, spec.status, spec.cacheTime.toString(), JSON.stringify(spec)]
);
} catch (e) {
console.error(e);
}
}

async deleteRepository(repositoryId: string): Promise<void> {
if (this.cacheDB == null) {
throw new Error(CACHE_UNAVAILABLE);
}
const rawRepositoryMetadata = await this.cacheDB.query(
//language=SQLite
`SELECT DATA
FROM CACHE_METADATA`
);
const repositoryMetadata: RecordCacheAddSpec[] =
rawRepositoryMetadata?.values?.map((set) => JSON.parse(set['DATA'])) ?? [];
const targetIndex = repositoryMetadata.findIndex((set) => set.setId === repositoryId);

if (targetIndex === -1) throw Error('Repository not found');

const { cachedIds, recordSetType } = repositoryMetadata[targetIndex];

const ids: Record<PropertyKey, number> = {};
repositoryMetadata
.flatMap((set) => set.cachedIds)
.forEach((id) => {
ids[id] ??= 0;
ids[id]++;
});
const recordsToErase = cachedIds.filter((id) => ids[id] <= 1);

await this.deleteCachedRecordsFromIds(recordsToErase, recordSetType);
await this.cacheDB.query(
//language=SQLite
`DELETE FROM CACHE_METADATA
WHERE SET_ID = ?`,
[repositoryId]
);
}

async listRepositories(): Promise<RecordCacheAddSpec[]> {
if (this.cacheDB == null) {
throw new Error(CACHE_UNAVAILABLE);
}
const repositories = await this.cacheDB.query(
//language=SQLite
`SELECT *
FROM CACHE_METADATA`
);
return repositories?.values?.map((entry) => JSON.parse(entry['DATA']) as RecordCacheAddSpec) ?? [];
}

/**
* @desc Helper method to fetch and parse repo metadata
*/
private async getRepoData(repositoryId: string) {
if (this.cacheDB == null) {
throw new Error(CACHE_UNAVAILABLE);
}
const repoData = await this.cacheDB.query(
//language=SQLite
`SELECT DATA
FROM CACHE_METADATA
WHERE SET_ID = ?`,
[repositoryId]
);
return JSON.parse(repoData?.values?.[0]['DATA']) ?? {};
}

async setRepositoryStatus(repositoryId: string, status: UserRecordCacheStatus): Promise<void> {
if (this.cacheDB == null) {
throw new Error(CACHE_UNAVAILABLE);
}
const currData = await this.getRepoData(repositoryId);
currData.status = status;
await this.cacheDB.query(
//language=SQLite
`UPDATE CACHE_METADATA
SET STATUS = ?,
CACHE_TIME = ?,
DATA = ?
WHERE SET_ID = ?`,
[status, JSON.stringify(currData.cacheTime), JSON.stringify(currData), repositoryId]
);
}

async checkForAbort(repositoryId: string): Promise<boolean> {
if (this.cacheDB == null) {
throw new Error(CACHE_UNAVAILABLE);
}
const metadata = await this.cacheDB.query(
//language=SQLite
`SELECT STATUS
FROM CACHE_METADATA
WHERE SET_ID = ?
LIMIT 1
`,
[repositoryId]
);

const cacheStatus = metadata?.values?.[0]['STATUS'];
if (cacheStatus) {
return cacheStatus === UserRecordCacheStatus.DELETING;
}
return true;
}

/**
* @desc fetch `n` records for a given recordset, supporting pagination
* @param recordSetID Recordset to filter from
Expand Down Expand Up @@ -102,6 +239,7 @@ class SQLiteRecordCacheService extends RecordCacheService {

return response;
}

async fetchPaginatedCachedIappRecords(recordSetIdList: string[], page: number, limit: number): Promise<IappRecord[]> {
if (!recordSetIdList || recordSetIdList.length === 0) {
return [];
Expand Down Expand Up @@ -283,7 +421,7 @@ class SQLiteRecordCacheService extends RecordCacheService {
};
return { cachedCentroid, cachedGeoJson };
}
async deleteCachedRecordsFromIds(idsToDelete: string[], setId: string, recordSetType: RecordSetType): Promise<void> {
async deleteCachedRecordsFromIds(idsToDelete: string[], recordSetType: RecordSetType): Promise<void> {
if (this.cacheDB == null) {
throw new Error(CACHE_UNAVAILABLE);
}
Expand Down Expand Up @@ -327,6 +465,10 @@ class SQLiteRecordCacheService extends RecordCacheService {
{
toVersion: 3,
statements: RECORD_CACHE_DB_MIGRATIONS_3
},
{
toVersion: 4,
statements: RECORD_CACHE_DB_MIGRATIONS_4
}
];
await sqlite.addUpgradeStatement(CACHE_DB_NAME, MIGRATIONS);
Expand Down

0 comments on commit 3a35fb3

Please sign in to comment.