| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- import { fetchMapData } from '@api/regions';
- import { SQLiteDatabase } from 'expo-sqlite';
- import { isNmDbRefreshing, refreshNmDatabase } from 'src/db';
- const NM_TABLES = new Set(['regions']);
- export const getData = async (
- db: SQLiteDatabase | null,
- regionId: number,
- name: string,
- callback: (data: any, avatars: string[]) => void
- ): Promise<void> => {
- const isNmTable = NM_TABLES.has(name);
- if (isNmTable && isNmDbRefreshing()) {
- console.warn(`[getData] nm DB is refreshing, falling back to API for "${name}"`);
- await fallbackToApi(regionId, callback);
- return;
- }
- if (!db) {
- if (isNmTable) {
- console.warn(`[getData] db is null for "${name}", falling back to API`);
- refreshNmDatabase();
- await fallbackToApi(regionId, callback);
- return;
- }
- throw new Error(`[getData] Database is null for table="${name}"`);
- }
- try {
- const regionRows = await db.getAllAsync<any>(`SELECT * FROM ${name} WHERE id = ?;`, [regionId]);
- const regionData = regionRows[0] ?? null;
- if (!regionData && isNmTable) {
- console.warn(
- `[getData] No record found for id=${regionId} in "${name}", falling back to API`
- );
- refreshNmDatabase();
- await fallbackToApi(regionId, callback);
- return;
- }
- const avatarIds: number[] = regionData?.visitors_avatars
- ? JSON.parse(regionData.visitors_avatars)
- : [];
- const avatars: string[] = [];
- for (const avatarId of avatarIds) {
- const avatarRows = await db.getAllAsync<any>(`SELECT * FROM avatars WHERE id = ?;`, [
- avatarId
- ]);
- if (avatarRows.length > 0) {
- avatars.push(avatarRows[0].data);
- }
- }
- setTimeout(() => callback(regionData, avatars), 0);
- } catch (error) {
- console.error('Error in getData:', error);
- if (isNmTable) {
- refreshNmDatabase();
- await fallbackToApi(regionId, callback);
- } else {
- throw error;
- }
- }
- };
- async function fallbackToApi(
- regionId: number,
- callback: (data: any, avatars: string[]) => void
- ): Promise<void> {
- try {
- const response = await fetchMapData(regionId);
- const regionData = response?.data ?? null;
- const avatars: string[] =
- regionData?.avatars?.slice(0, 3).map((a: { data: string; id: number }) => a.data) ?? [];
- setTimeout(() => callback(regionData, avatars), 0);
- } catch (apiError) {
- console.error('[getData] API fallback failed:', apiError);
- throw apiError;
- }
- }
|