Added sqlite
This commit is contained in:
parent
73a7c93e64
commit
f01186df79
14 changed files with 784 additions and 382 deletions
|
|
@ -1,4 +1,3 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:googleapis/drive/v3.dart' as drive;
|
||||
|
|
@ -6,7 +5,7 @@ import 'package:http/http.dart' as http;
|
|||
|
||||
const appFolderName = 'MO-Fuel-Tax-Back';
|
||||
const receiptsFolderName = 'receipts';
|
||||
const dataFileName = 'fuel_tax_data.json';
|
||||
const dataFileName = 'fuel_tax_tracker.db';
|
||||
|
||||
const _folderMimeType = 'application/vnd.google-apps.folder';
|
||||
|
||||
|
|
@ -17,6 +16,16 @@ class DriveFolder {
|
|||
DriveFolder({required this.id, required this.name});
|
||||
}
|
||||
|
||||
class DriveDataFileInfo {
|
||||
final String id;
|
||||
|
||||
/// Cheap change-detection signal: compare against the last value seen to
|
||||
/// decide whether a pull is actually needed, without downloading content.
|
||||
final String? md5Checksum;
|
||||
|
||||
DriveDataFileInfo({required this.id, required this.md5Checksum});
|
||||
}
|
||||
|
||||
class DriveLockFile {
|
||||
final String id;
|
||||
final String username;
|
||||
|
|
@ -87,23 +96,21 @@ class DriveService {
|
|||
return created.id!;
|
||||
}
|
||||
|
||||
Future<String?> findDataFileId(String appFolderId) async {
|
||||
/// Looks up the shared data file's ID and md5 checksum without
|
||||
/// downloading its content, so sync can cheaply decide whether a pull is
|
||||
/// actually needed.
|
||||
Future<DriveDataFileInfo?> findDataFile(String appFolderId) async {
|
||||
final result = await _api.files.list(
|
||||
q: "'$appFolderId' in parents and trashed=false and name='$dataFileName'",
|
||||
orderBy: 'modifiedTime desc',
|
||||
$fields: 'files(id,name)',
|
||||
$fields: 'files(id,name,md5Checksum)',
|
||||
spaces: 'drive',
|
||||
);
|
||||
return (result.files ?? []).firstOrNullWithId();
|
||||
}
|
||||
|
||||
Future<String> downloadTextFile(String fileId) async {
|
||||
final media = await _api.files.get(
|
||||
fileId,
|
||||
downloadOptions: drive.DownloadOptions.fullMedia,
|
||||
) as drive.Media;
|
||||
final bytes = await _collectBytes(media.stream);
|
||||
return utf8.decode(bytes);
|
||||
final files = result.files ?? <drive.File>[];
|
||||
if (files.isEmpty) return null;
|
||||
final first = files.first;
|
||||
if (first.id == null) return null;
|
||||
return DriveDataFileInfo(id: first.id!, md5Checksum: first.md5Checksum);
|
||||
}
|
||||
|
||||
Future<List<int>> downloadFileBytes(String fileId) async {
|
||||
|
|
@ -115,17 +122,20 @@ class DriveService {
|
|||
}
|
||||
|
||||
/// Creates the data file if [existingFileId] is null, otherwise
|
||||
/// overwrites its content. Returns the (possibly new) file ID.
|
||||
Future<String> uploadDataFile({
|
||||
/// overwrites its content with the bytes of the local sqlite database
|
||||
/// file (see [DriveSyncService]). Returns the (possibly new) file ID and
|
||||
/// its fresh md5 checksum, so the caller can remember it for
|
||||
/// change-detection on the next sync without an extra round-trip.
|
||||
Future<DriveDataFileInfo> uploadDataFile({
|
||||
required String appFolderId,
|
||||
required String? existingFileId,
|
||||
required String jsonContent,
|
||||
required File localSnapshotFile,
|
||||
}) async {
|
||||
final bytes = utf8.encode(jsonContent);
|
||||
final length = await localSnapshotFile.length();
|
||||
final media = drive.Media(
|
||||
Stream.value(bytes),
|
||||
bytes.length,
|
||||
contentType: 'application/json',
|
||||
localSnapshotFile.openRead(),
|
||||
length,
|
||||
contentType: 'application/x-sqlite3',
|
||||
);
|
||||
|
||||
if (existingFileId != null) {
|
||||
|
|
@ -133,8 +143,9 @@ class DriveService {
|
|||
drive.File(),
|
||||
existingFileId,
|
||||
uploadMedia: media,
|
||||
$fields: 'id,md5Checksum',
|
||||
);
|
||||
return updated.id ?? existingFileId;
|
||||
return DriveDataFileInfo(id: updated.id ?? existingFileId, md5Checksum: updated.md5Checksum);
|
||||
}
|
||||
|
||||
final created = await _api.files.create(
|
||||
|
|
@ -142,8 +153,9 @@ class DriveService {
|
|||
..name = dataFileName
|
||||
..parents = [appFolderId],
|
||||
uploadMedia: media,
|
||||
$fields: 'id,md5Checksum',
|
||||
);
|
||||
return created.id!;
|
||||
return DriveDataFileInfo(id: created.id!, md5Checksum: created.md5Checksum);
|
||||
}
|
||||
|
||||
Future<String> uploadReceiptImage({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue