Adatbázis és szinkronizációs hibajavítások
This commit is contained in:
@@ -23,6 +23,7 @@ import 'package:terepi_seged/services/note_photo_service.dart';
|
|||||||
import 'package:terepi_seged/services/ntrip_service.dart';
|
import 'package:terepi_seged/services/ntrip_service.dart';
|
||||||
import 'package:terepi_seged/services/project_service.dart';
|
import 'package:terepi_seged/services/project_service.dart';
|
||||||
import 'package:terepi_seged/services/stakeout_service.dart';
|
import 'package:terepi_seged/services/stakeout_service.dart';
|
||||||
|
import 'package:terepi_seged/services/stakeout_sync_service.dart';
|
||||||
import 'package:terepi_seged/services/tilt_service.dart';
|
import 'package:terepi_seged/services/tilt_service.dart';
|
||||||
import 'package:terepi_seged/services/track_sync_service.dart';
|
import 'package:terepi_seged/services/track_sync_service.dart';
|
||||||
import 'package:terepi_seged/services/ts_sync_service.dart';
|
import 'package:terepi_seged/services/ts_sync_service.dart';
|
||||||
@@ -67,6 +68,7 @@ Future<void> main() async {
|
|||||||
Get.put(LayerImportService(), permanent: true);
|
Get.put(LayerImportService(), permanent: true);
|
||||||
Get.put(TrackSyncService(), permanent: true);
|
Get.put(TrackSyncService(), permanent: true);
|
||||||
Get.put(LayerSyncService());
|
Get.put(LayerSyncService());
|
||||||
|
Get.put(StakeoutSyncService());
|
||||||
Get.put(TsSyncService());
|
Get.put(TsSyncService());
|
||||||
Get.put(TiltService());
|
Get.put(TiltService());
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
@@ -482,7 +483,10 @@ class AppDatabase {
|
|||||||
Future<int> insertTrack(Track track) async {
|
Future<int> insertTrack(Track track) async {
|
||||||
final db = await database;
|
final db = await database;
|
||||||
final map = _withSyncColumns(track.toMap());
|
final map = _withSyncColumns(track.toMap());
|
||||||
map['device_id'] ??= DeviceIdentityService.to.deviceId;
|
map['device_id'] ??= Get.isRegistered<DeviceIdentityService>() &&
|
||||||
|
DeviceIdentityService.to.isReady
|
||||||
|
? DeviceIdentityService.to.appInstanceId
|
||||||
|
: null;
|
||||||
return db.insert('tracks', map);
|
return db.insert('tracks', map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,7 +863,10 @@ class AppDatabase {
|
|||||||
Future<int> insertMeasuredPoint(MeasuredPoint point) async {
|
Future<int> insertMeasuredPoint(MeasuredPoint point) async {
|
||||||
final db = await database;
|
final db = await database;
|
||||||
final map = _withSyncColumns(point.toMap());
|
final map = _withSyncColumns(point.toMap());
|
||||||
map['device_id'] ??= DeviceIdentityService.to.deviceId;
|
map['device_id'] ??= Get.isRegistered<DeviceIdentityService>() &&
|
||||||
|
DeviceIdentityService.to.isReady
|
||||||
|
? DeviceIdentityService.to.appInstanceId
|
||||||
|
: null;
|
||||||
return db.insert('measured_points', map);
|
return db.insert('measured_points', map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -951,7 +958,11 @@ class AppDatabase {
|
|||||||
Future<int> insertStakeoutPoint(StakeoutPoint p) async {
|
Future<int> insertStakeoutPoint(StakeoutPoint p) async {
|
||||||
final db = await database;
|
final db = await database;
|
||||||
final map = p.toMap();
|
final map = p.toMap();
|
||||||
map['device_id'] ??= DeviceIdentityService.to.deviceId;
|
map['device_id'] ??= Get.isRegistered<DeviceIdentityService>() &&
|
||||||
|
DeviceIdentityService.to.isReady
|
||||||
|
? DeviceIdentityService.to.appInstanceId
|
||||||
|
: null;
|
||||||
|
;
|
||||||
return db.insert('stakeout_points', map);
|
return db.insert('stakeout_points', map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -971,7 +982,10 @@ class AppDatabase {
|
|||||||
limit: 1);
|
limit: 1);
|
||||||
if (dup.isNotEmpty) continue;
|
if (dup.isNotEmpty) continue;
|
||||||
final map = p.toMap();
|
final map = p.toMap();
|
||||||
map['device_id'] ??= DeviceIdentityService.to.deviceId;
|
map['device_id'] ??= Get.isRegistered<DeviceIdentityService>() &&
|
||||||
|
DeviceIdentityService.to.isReady
|
||||||
|
? DeviceIdentityService.to.appInstanceId
|
||||||
|
: null;
|
||||||
await txn.insert('stakeout_points', map);
|
await txn.insert('stakeout_points', map);
|
||||||
inserted++;
|
inserted++;
|
||||||
}
|
}
|
||||||
@@ -1249,4 +1263,18 @@ class AppDatabase {
|
|||||||
await db.insert('imported_layers', map,
|
await db.insert('imported_layers', map,
|
||||||
conflictAlgorithm: ConflictAlgorithm.replace);
|
conflictAlgorithm: ConflictAlgorithm.replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Egyszeri javítás: a korábban ANDROID_ID-vel (vagy üresen) beírt
|
||||||
|
/// device_id-k cseréje az appInstanceId-re. A sorok ezen az eszközön
|
||||||
|
/// keletkeztek, így a csere helyes; a sync_status visszaáll pending-re,
|
||||||
|
/// hogy a helyes érték felmenjen.
|
||||||
|
Future<void> repairDeviceIds(String correctId) async {
|
||||||
|
final db = await database;
|
||||||
|
for (final t in ['measured_points', 'tracks', 'stakeout_points']) {
|
||||||
|
await db.rawUpdate(
|
||||||
|
"UPDATE $t SET device_id = ?, sync_status = 'pending' "
|
||||||
|
"WHERE device_id IS NOT NULL AND length(device_id) <> 36",
|
||||||
|
[correctId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
|
import 'package:terepi_seged/services/app_database.dart';
|
||||||
import 'package:terepi_seged/services/app_logger.dart';
|
import 'package:terepi_seged/services/app_logger.dart';
|
||||||
import 'package:terepi_seged/services/firebase_logger.dart';
|
import 'package:terepi_seged/services/firebase_logger.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
@@ -61,6 +62,7 @@ class DeviceIdentityService extends GetxService {
|
|||||||
// Háttérben regisztrálás — nem blokkolja az UI-t
|
// Háttérben regisztrálás — nem blokkolja az UI-t
|
||||||
_isReady = true;
|
_isReady = true;
|
||||||
unawaited(registerDevice());
|
unawaited(registerDevice());
|
||||||
|
unawaited(AppDatabase.instance.repairDeviceIds(info.appInstanceId));
|
||||||
|
|
||||||
FirebaseLogger.setDeviceIdentifier(info.deviceId, deviceLabel.value);
|
FirebaseLogger.setDeviceIdentifier(info.deviceId, deviceLabel.value);
|
||||||
FirebaseLogger.setKey('model', model);
|
FirebaseLogger.setKey('model', model);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import '../models/imported_layer_meta.dart';
|
|||||||
class LayerSyncService extends GetxService {
|
class LayerSyncService extends GetxService {
|
||||||
static LayerSyncService get to => Get.find();
|
static LayerSyncService get to => Get.find();
|
||||||
|
|
||||||
static const bucket = 'ts-layers';
|
static const bucket = 'terepi_seged-layers';
|
||||||
|
|
||||||
final isSyncing = false.obs;
|
final isSyncing = false.obs;
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class LayerSyncService extends GetxService {
|
|||||||
Future<void> _pullProjectLayers(
|
Future<void> _pullProjectLayers(
|
||||||
int localProjectId, String projectUuid) async {
|
int localProjectId, String projectUuid) async {
|
||||||
final rows = await _client
|
final rows = await _client
|
||||||
.from('ts_layers')
|
.from('terepi_seged_layers')
|
||||||
.select()
|
.select()
|
||||||
.eq('project_id', projectUuid)
|
.eq('project_id', projectUuid)
|
||||||
.filter('deleted_at', 'is', null);
|
.filter('deleted_at', 'is', null);
|
||||||
@@ -126,13 +126,13 @@ class LayerSyncService extends GetxService {
|
|||||||
|
|
||||||
// 2. Verzió léptetése, ha már létezik a sor.
|
// 2. Verzió léptetése, ha már létezik a sor.
|
||||||
final existing = await _client
|
final existing = await _client
|
||||||
.from('ts_layers')
|
.from('terepi_seged_layers')
|
||||||
.select('version')
|
.select('version')
|
||||||
.eq('id', id)
|
.eq('id', id)
|
||||||
.maybeSingle();
|
.maybeSingle();
|
||||||
final newVersion = ((existing?['version'] as int?) ?? 0) + 1;
|
final newVersion = ((existing?['version'] as int?) ?? 0) + 1;
|
||||||
|
|
||||||
await _client.from('ts_layers').upsert({
|
await _client.from('terepi_seged_layers').upsert({
|
||||||
'id': id,
|
'id': id,
|
||||||
'project_id': projectUuid,
|
'project_id': projectUuid,
|
||||||
'name': layer.name,
|
'name': layer.name,
|
||||||
@@ -154,7 +154,7 @@ class LayerSyncService extends GetxService {
|
|||||||
/// Réteg visszavonása a megosztásból (soft delete a szerveren;
|
/// Réteg visszavonása a megosztásból (soft delete a szerveren;
|
||||||
/// a lokális cache-példányok megmaradnak az eszközökön).
|
/// a lokális cache-példányok megmaradnak az eszközökön).
|
||||||
Future<void> unpublishLayer(String layerId) async {
|
Future<void> unpublishLayer(String layerId) async {
|
||||||
await _client.from('ts_layers').update({
|
await _client.from('terepi_seged_layers').update({
|
||||||
'deleted_at': DateTime.now().toUtc().toIso8601String(),
|
'deleted_at': DateTime.now().toUtc().toIso8601String(),
|
||||||
}).eq('id', layerId);
|
}).eq('id', layerId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class StakeoutSyncService extends GetxService {
|
|||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
await _client.from('ts_stakeout_points').upsert(payload);
|
await _client.from('terepi_seged_stakeout_points').upsert(payload);
|
||||||
await _db.markSyncedByUuid(
|
await _db.markSyncedByUuid(
|
||||||
'stakeout_points', rows.map((r) => r['uuid'] as String).toList());
|
'stakeout_points', rows.map((r) => r['uuid'] as String).toList());
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ class StakeoutSyncService extends GetxService {
|
|||||||
var maxSeen = cursor;
|
var maxSeen = cursor;
|
||||||
|
|
||||||
final rows = await _client
|
final rows = await _client
|
||||||
.from('ts_stakeout_points')
|
.from('terepi_seged_stakeout_points')
|
||||||
.select()
|
.select()
|
||||||
.eq('project_id', project.uuid)
|
.eq('project_id', project.uuid)
|
||||||
.gt('updated_at', cursor)
|
.gt('updated_at', cursor)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:connectivity_plus/connectivity_plus.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
import 'package:terepi_seged/services/device_identity_service.dart';
|
import 'package:terepi_seged/services/device_identity_service.dart';
|
||||||
|
import 'package:terepi_seged/services/stakeout_sync_service.dart';
|
||||||
|
|
||||||
import 'app_database.dart';
|
import 'app_database.dart';
|
||||||
import 'layer_sync_service.dart';
|
import 'layer_sync_service.dart';
|
||||||
@@ -93,6 +94,10 @@ class TsSyncService extends GetxService {
|
|||||||
await LayerSyncService.to.pullAll();
|
await LayerSyncService.to.pullAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Get.isRegistered<StakeoutSyncService>()) {
|
||||||
|
await StakeoutSyncService.to.sync();
|
||||||
|
}
|
||||||
|
|
||||||
lastSyncedAt.value = DateTime.now();
|
lastSyncedAt.value = DateTime.now();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
lastError.value = e.toString();
|
lastError.value = e.toString();
|
||||||
|
|||||||
Reference in New Issue
Block a user