|
1 | 1 | import { BindParams } from 'sql.js'; |
2 | 2 | import initSqlJs from 'sql.js'; |
3 | | -import { loadFromIndexedDB, saveToIndexedDB } from '@/data/indexedDatabase'; |
| 3 | +import { loadFromIndexedDB, saveToIndexedDB, saveToIndexedDBBA } from '@/data/indexedDatabase'; |
| 4 | +import * as FileSystem from 'expo-file-system'; |
| 5 | +import * as Sharing from 'expo-sharing'; |
| 6 | +import logger from '@/logger'; |
| 7 | +import * as DocumentPicker from 'expo-document-picker'; |
4 | 8 | export type SQLiteDatabase = any; |
5 | 9 | const sqlPromise = initSqlJs({ |
6 | 10 | locateFile: (file) => `https://sql.js.org/dist/${file}`, |
@@ -60,5 +64,72 @@ export async function openDatabaseAsync(databaseName: string, options?: any): Pr |
60 | 64 | closeAsync: async () => { |
61 | 65 | db.close(); |
62 | 66 | }, |
| 67 | + export: () => { |
| 68 | + return db.export(); |
| 69 | + }, |
| 70 | + import: async (data: Uint8Array) => { |
| 71 | + await saveToIndexedDBBA(data, databaseName); |
| 72 | + }, |
63 | 73 | }; |
64 | 74 | } |
| 75 | + |
| 76 | +export const backupDatabase = async (db: SQLiteDatabase, backupName: string) => { |
| 77 | + try { |
| 78 | + const fileContent = await db.export(); |
| 79 | + const blob = new Blob([fileContent], { type: 'application/x-sqlite3' }); |
| 80 | + const url = URL.createObjectURL(blob); |
| 81 | + const link = document.createElement('a'); |
| 82 | + link.href = url; |
| 83 | + link.download = backupName; |
| 84 | + link.click(); |
| 85 | + URL.revokeObjectURL(url); |
| 86 | + } catch (err) { |
| 87 | + logger.error('Failed to backup', err); |
| 88 | + } |
| 89 | +}; |
| 90 | + |
| 91 | +export const restoreDatabase = async (db: SQLiteDatabase) => { |
| 92 | + try { |
| 93 | + const input = document.createElement('input'); |
| 94 | + input.type = 'file'; |
| 95 | + input.accept = '*/*'; |
| 96 | + |
| 97 | + return new Promise<void>((resolve, reject) => { |
| 98 | + input.onchange = async (event: any) => { |
| 99 | + const file = event.target.files[0]; |
| 100 | + if (!file) { |
| 101 | + resolve(undefined); |
| 102 | + return; |
| 103 | + } |
| 104 | + |
| 105 | + const reader = new FileReader(); |
| 106 | + reader.onload = async (e) => { |
| 107 | + try { |
| 108 | + const fileContent = e.target?.result as ArrayBuffer | null; |
| 109 | + if (!fileContent) { |
| 110 | + reject('Corrupted file!'); |
| 111 | + return; |
| 112 | + } |
| 113 | + |
| 114 | + const uint8Array = new Uint8Array(fileContent); |
| 115 | + // @ts-ignore |
| 116 | + await db.import(uint8Array); |
| 117 | + resolve(undefined); |
| 118 | + } catch (error) { |
| 119 | + reject(error?.message || 'Unknown error!'); |
| 120 | + } |
| 121 | + }; |
| 122 | + |
| 123 | + reader.onerror = () => { |
| 124 | + reject('Error reading the file!'); |
| 125 | + }; |
| 126 | + |
| 127 | + reader.readAsArrayBuffer(file); |
| 128 | + }; |
| 129 | + |
| 130 | + input.click(); |
| 131 | + }); |
| 132 | + } catch (err) { |
| 133 | + logger.error('Failed to backup', err); |
| 134 | + } |
| 135 | +}; |
0 commit comments