ObjectBox

This commit is contained in:
Sven committed 2025-10-23 11:48:22 +02:00
1 parent f8317be627
commit 809bffc7a2
9 files changed
+125 -42

No files matched your search

+1 -1
View File
@@ -76,7 +76,7 @@ class _AcceptedJobsPageState extends State<AcceptedJobsPage>
for (var job in _jobs) {
var bottomText =
"${job.id}\n${job.tours[0].comp}\n${job.tours[0].street}\n${job.tours[0].city}";
"${job.externalId}\n${job.tours[0].comp}\n${job.tours[0].street}\n${job.tours[0].city}";
if (job.rem.trim().isNotEmpty) {
bottomText += "\n\n${job.rem.trim()}";
}
+7 -7
View File
@@ -143,7 +143,7 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> with ProducerMixin,
),
],
),
Text('Auftragsnummer: ${job.id}'),
Text('Auftragsnummer: ${job.externalId}'),
Text(job.tours[0].comp),
Text(job.tours[0].street),
Text(job.tours[0].city),
@@ -187,9 +187,9 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> with ProducerMixin,
Row(children: [
Expanded(
child: getDefaultButton(!job.global ? 'Ablehnen' : 'Ignorieren', () {
job.sendMessage(
sendMessage(
routingKey: Constants.messageTopicRemoveJob,
payload: RemoveJobMessage(id: job.id),
payload: RemoveJobMessage(id: job.externalId),
);
_sendAnswer(job, !job.global ? 2 : 3);
@@ -202,9 +202,9 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> with ProducerMixin,
const SizedBox(width: 20),
Expanded(
child: getDefaultButton('Annehmen', () {
job.sendMessage(
sendMessage(
routingKey: Constants.messageTopicRemoveJob,
payload: RemoveJobMessage(id: job.id),
payload: RemoveJobMessage(id: job.externalId),
);
_sendAnswer(job, 1);
@@ -231,7 +231,7 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> with ProducerMixin,
var currentPosition = await MyApp.getCurrentPosition();
var message = Reaction();
message.id = job.id;
message.id = job.externalId; // Use external ID for network communication
message.ver = job.ver.toString();
message.item = item;
message.track = Track();
@@ -244,7 +244,7 @@ class _AssignedJobsPageState extends State<AssignedJobsPage> with ProducerMixin,
sendMessage(
routingKey: Constants.messageTopicRemoveState0JobFromMap,
payload: RemoveState0JobFromMapMessage(jobId: job.id),
payload: RemoveState0JobFromMapMessage(jobId: job.externalId), // Use external ID
);
sendMessage(
+1 -1
View File
@@ -69,7 +69,7 @@ class _FinishedJobsPageState extends State<FinishedJobsPage>
for (var job in _jobs) {
var bottomText =
"${job.id}\n${job.tours[0].comp}\n${job.tours[0].street}\n${job.tours[0].city}";
"${job.externalId}\n${job.tours[0].comp}\n${job.tours[0].street}\n${job.tours[0].city}";
if (job.rem.trim().isNotEmpty) {
bottomText += "\n\n${job.rem.trim()}";
}
+16 -5
View File
@@ -1,5 +1,5 @@
import 'package:objectbox/objectbox.dart';
import 'package:stadtbote/main.dart';
import 'package:stadtbote/objectbox.g.dart';
import 'package:stadtbote/tools/util.dart';
@Entity()
@@ -7,6 +7,10 @@ class ChatMessage {
@Id()
int id = 0;
// External ID from server
@Unique()
late int externalId;
late int time;
late String from;
@@ -21,7 +25,8 @@ class ChatMessage {
factory ChatMessage.fromJson(Map<String, dynamic> json) {
final message = ChatMessage();
message.id = json['id'] as int? ?? 0;
message.id = 0; // Let ObjectBox assign the ID
message.externalId = json['id'] as int; // Store external ID separately
message.time = json['time'] as int;
message.from = json['from'] as String;
message.subj = json['subj'] as String;
@@ -32,7 +37,7 @@ class ChatMessage {
Map<String, dynamic> toJson() {
return {
'id': id,
'id': externalId, // Use external ID for JSON
'time': time,
'from': from,
'subj': subj,
@@ -42,10 +47,16 @@ class ChatMessage {
}
static Future<ChatMessage> mergeFromJson(Map<String, dynamic> json) async {
var availableMessage = MyApp.objectBoxStore.box<ChatMessage>().get(json["id"] as int);
final box = MyApp.objectBoxStore.box<ChatMessage>();
final externalId = json["id"] as int;
// Find message by external ID
final query = box.query(ChatMessage_.externalId.equals(externalId)).build();
var availableMessage = query.findFirst();
query.close();
if (availableMessage != null) {
availableMessage.id = json["id"];
availableMessage.externalId = json["id"];
availableMessage.time = json["time"];
availableMessage.from = json["from"];
availableMessage.subj = json["subj"];
+8 -4
View File
@@ -1,13 +1,16 @@
import 'dart:convert';
import 'package:dart_mq/dart_mq.dart';
import 'package:objectbox/objectbox.dart';
import 'package:stadtbote/model/job_tour.dart';
@Entity()
class Job with ProducerMixin {
class Job {
@Id()
int id = 0;
// External ID from server
@Unique()
late int externalId;
late String ver;
late int state;
String? crFilter;
@@ -35,7 +38,8 @@ class Job with ProducerMixin {
factory Job.fromJson(Map<String, dynamic> json) {
final job = Job();
job.id = json['id'] as int? ?? 0;
job.id = 0; // Let ObjectBox assign the ID
job.externalId = json['id'] as int; // Store external ID separately
job.ver = json['ver'] as String;
job.state = json['state'] as int;
job.crFilter = json['cr_filter'] as String?;
@@ -53,7 +57,7 @@ class Job with ProducerMixin {
Map<String, dynamic> toJson() {
return {
'id': id,
'id': externalId, // Use external ID for JSON
'ver': ver,
'state': state,
'cr_filter': crFilter,
+17 -3
View File
@@ -34,7 +34,7 @@
},
{
"id": "3:808686831791135454",
"lastPropertyId": "11:3214338916427673014",
"lastPropertyId": "12:5320049580625017283",
"name": "Job",
"properties": [
{
@@ -92,6 +92,13 @@
"id": "11:3214338916427673014",
"name": "toursJson",
"type": 9
},
{
"id": "12:5320049580625017283",
"name": "externalId",
"type": 6,
"flags": 40,
"indexId": "1:2108836818156887439"
}
],
"relations": []
@@ -297,7 +304,7 @@
},
{
"id": "11:8606238749478059367",
"lastPropertyId": "6:7798301556204918939",
"lastPropertyId": "7:4056540326670791484",
"name": "ChatMessage",
"properties": [
{
@@ -330,6 +337,13 @@
"id": "6:7798301556204918939",
"name": "read",
"type": 1
},
{
"id": "7:4056540326670791484",
"name": "externalId",
"type": 6,
"flags": 40,
"indexId": "2:428171949166894655"
}
],
"relations": []
@@ -370,7 +384,7 @@
}
],
"lastEntityId": "12:4865606913057136676",
"lastIndexId": "0:0",
"lastIndexId": "2:428171949166894655",
"lastRelationId": "0:0",
"lastSequenceId": "0:0",
"modelVersion": 5,
+44 -6
View File
@@ -65,7 +65,7 @@ final _entities = <obx_int.ModelEntity>[
obx_int.ModelEntity(
id: const obx_int.IdUid(3, 808686831791135454),
name: 'Job',
lastPropertyId: const obx_int.IdUid(11, 3214338916427673014),
lastPropertyId: const obx_int.IdUid(12, 5320049580625017283),
flags: 0,
properties: <obx_int.ModelProperty>[
obx_int.ModelProperty(
@@ -134,6 +134,13 @@ final _entities = <obx_int.ModelEntity>[
type: 9,
flags: 0,
),
obx_int.ModelProperty(
id: const obx_int.IdUid(12, 5320049580625017283),
name: 'externalId',
type: 6,
flags: 40,
indexId: const obx_int.IdUid(1, 2108836818156887439),
),
],
relations: <obx_int.ModelRelation>[],
backlinks: <obx_int.ModelBacklink>[],
@@ -375,7 +382,7 @@ final _entities = <obx_int.ModelEntity>[
obx_int.ModelEntity(
id: const obx_int.IdUid(11, 8606238749478059367),
name: 'ChatMessage',
lastPropertyId: const obx_int.IdUid(6, 7798301556204918939),
lastPropertyId: const obx_int.IdUid(7, 4056540326670791484),
flags: 0,
properties: <obx_int.ModelProperty>[
obx_int.ModelProperty(
@@ -414,6 +421,13 @@ final _entities = <obx_int.ModelEntity>[
type: 1,
flags: 0,
),
obx_int.ModelProperty(
id: const obx_int.IdUid(7, 4056540326670791484),
name: 'externalId',
type: 6,
flags: 40,
indexId: const obx_int.IdUid(2, 428171949166894655),
),
],
relations: <obx_int.ModelRelation>[],
backlinks: <obx_int.ModelBacklink>[],
@@ -499,7 +513,7 @@ obx_int.ModelDefinition getObjectBoxModel() {
final model = obx_int.ModelInfo(
entities: _entities,
lastEntityId: const obx_int.IdUid(12, 4865606913057136676),
lastIndexId: const obx_int.IdUid(0, 0),
lastIndexId: const obx_int.IdUid(2, 428171949166894655),
lastRelationId: const obx_int.IdUid(0, 0),
lastSequenceId: const obx_int.IdUid(0, 0),
retiredEntityUids: const [3121960281516643928, 3330049220205502332],
@@ -578,7 +592,7 @@ obx_int.ModelDefinition getObjectBoxModel() {
: fbb.writeString(object.crFilter!);
final remOffset = fbb.writeString(object.rem);
final toursJsonOffset = fbb.writeString(object.toursJson);
fbb.startTable(12);
fbb.startTable(13);
fbb.addInt64(0, object.id);
fbb.addOffset(1, verOffset);
fbb.addInt64(2, object.state);
@@ -590,6 +604,7 @@ obx_int.ModelDefinition getObjectBoxModel() {
fbb.addOffset(8, remOffset);
fbb.addInt64(9, object.delayOrderTime);
fbb.addOffset(10, toursJsonOffset);
fbb.addInt64(11, object.externalId);
fbb.finish(fbb.endTable());
return object.id;
},
@@ -636,7 +651,13 @@ obx_int.ModelDefinition getObjectBoxModel() {
)
..toursJson = const fb.StringReader(
asciiOptimization: true,
).vTableGet(buffer, rootOffset, 24, '');
).vTableGet(buffer, rootOffset, 24, '')
..externalId = const fb.Int64Reader().vTableGet(
buffer,
rootOffset,
26,
0,
);
return object;
},
@@ -894,13 +915,14 @@ obx_int.ModelDefinition getObjectBoxModel() {
final fromOffset = fbb.writeString(object.from);
final subjOffset = fbb.writeString(object.subj);
final textOffset = fbb.writeString(object.text);
fbb.startTable(7);
fbb.startTable(8);
fbb.addInt64(0, object.id);
fbb.addInt64(1, object.time);
fbb.addOffset(2, fromOffset);
fbb.addOffset(3, subjOffset);
fbb.addOffset(4, textOffset);
fbb.addBool(5, object.read);
fbb.addInt64(6, object.externalId);
fbb.finish(fbb.endTable());
return object.id;
},
@@ -925,6 +947,12 @@ obx_int.ModelDefinition getObjectBoxModel() {
rootOffset,
14,
false,
)
..externalId = const fb.Int64Reader().vTableGet(
buffer,
rootOffset,
16,
0,
);
return object;
@@ -1055,6 +1083,11 @@ class Job_ {
static final toursJson = obx.QueryStringProperty<Job>(
_entities[1].properties[10],
);
/// See [Job.externalId].
static final externalId = obx.QueryIntegerProperty<Job>(
_entities[1].properties[11],
);
}
/// [LocationStatus] entity fields to define ObjectBox queries.
@@ -1251,6 +1284,11 @@ class ChatMessage_ {
static final read = obx.QueryBooleanProperty<ChatMessage>(
_entities[8].properties[5],
);
/// See [ChatMessage.externalId].
static final externalId = obx.QueryIntegerProperty<ChatMessage>(
_entities[8].properties[6],
);
}
/// [TaskInfo] entity fields to define ObjectBox queries.
+12 -11
View File
@@ -13,6 +13,7 @@ import 'package:stadtbote/tools/messages/job_deleted_message.dart';
import 'package:stadtbote/tools/messages/job_received_message.dart';
import 'package:stadtbote/tools/messages/refresh_badges_message.dart';
import 'package:stadtbote/tools/messages/remove_job_message.dart';
import 'package:stadtbote/tools/mqtt_core.dart';
import 'package:stadtbote/tools/util.dart';
import '../tools/messages/publish_payload_message.dart';
@@ -216,9 +217,9 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
jobMap.remove(job.id);
job.sendMessage(
MqttCore.instance.sendMessage(
routingKey: Constants.messageTopicRemoveJob,
payload: RemoveJobMessage(id: job.id),
payload: RemoveJobMessage(id: job.externalId),
);
setState(() {});
@@ -233,9 +234,9 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
jobMap.remove(job.id);
job.sendMessage(
MqttCore.instance.sendMessage(
routingKey: Constants.messageTopicRemoveJob,
payload: RemoveJobMessage(id: job.id),
payload: RemoveJobMessage(id: job.externalId),
);
setState(() {});
@@ -350,9 +351,9 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
jobMap.remove(job.id);
job.sendMessage(
MqttCore.instance.sendMessage(
routingKey: Constants.messageTopicRemoveJob,
payload: RemoveJobMessage(id: job.id),
payload: RemoveJobMessage(id: job.externalId),
);
setState(() {});
@@ -367,9 +368,9 @@ Future<List<Widget>> _fetchJobWidgets(StateSetter dialogState, Function() onFini
jobMap.remove(job.id);
job.sendMessage(
MqttCore.instance.sendMessage(
routingKey: Constants.messageTopicRemoveJob,
payload: RemoveJobMessage(id: job.id),
payload: RemoveJobMessage(id: job.externalId),
);
setState(() {});
@@ -394,7 +395,7 @@ _sendAnswer(SharedMapReference mapReference, Job job, int item) async {
var currentPosition = await MyApp.getCurrentPosition();
var message = Reaction();
message.id = job.id;
message.id = job.externalId; // Use external ID for network communication
message.ver = job.ver.toString();
message.item = item;
message.track = Track();
@@ -405,12 +406,12 @@ _sendAnswer(SharedMapReference mapReference, Job job, int item) async {
message.track.pos!.long = currentPosition != null ? currentPosition.longitude : 0.0;
message.track.pos!.acc = currentPosition != null ? currentPosition.accuracy.toInt() : 0;
job.sendMessage(
MqttCore.instance.sendMessage(
routingKey: Constants.messageTopicPublishPayload,
payload: PublishPayloadMessage(topic: "reaction", message: message.toJson(), acknowledgeRequired: true),
);
job.sendMessage(
MqttCore.instance.sendMessage(
routingKey: Constants.messageTopicUpdateBadges,
payload: RefreshBadgesMessage(),
);
+19 -4
View File
@@ -394,6 +394,17 @@ class MqttCore with ProducerMixin, ConsumerMixin {
Job newJob = Job.fromJson(payloadData);
final box = MyApp.objectBoxStore.box<Job>();
// Check if job already exists by externalId
final query = box.query(Job_.externalId.equals(newJob.externalId)).build();
final existingJob = query.findFirst();
query.close();
if (existingJob != null) {
// Update existing job
newJob.id = existingJob.id;
}
box.put(newJob);
if (newJob.state == Constants.stateAssigned) {
@@ -416,10 +427,14 @@ class MqttCore with ProducerMixin, ConsumerMixin {
var jobDelMessage = JobDelMessage.fromJson(payloadData);
final box = MyApp.objectBoxStore.box<Job>();
var job = box.get(jobDelMessage.id);
// Find job by external ID
final query = box.query(Job_.externalId.equals(jobDelMessage.id)).build();
final job = query.findFirst();
query.close();
if (job != null) {
box.remove(jobDelMessage.id);
box.remove(job.id); // Use ObjectBox ID for removal
sendMessage(
routingKey: Constants.messageTopicJobDeleted,
@@ -613,7 +628,7 @@ class MqttCore with ProducerMixin, ConsumerMixin {
for (var job in jobs) {
SyncJobMessageJob syncJob = SyncJobMessageJob();
syncJob.state = job.state;
syncJob.id = job.id;
syncJob.id = job.externalId; // Use external ID for network communication
syncJob.ver = job.ver.toString();
answer.sync.jobs.add(syncJob);
}
@@ -687,7 +702,7 @@ class MqttCore with ProducerMixin, ConsumerMixin {
void _acknowlegdeJob(Job job) {
var message = AcknowledgeJobReceived();
message.id = job.id;
message.id = job.externalId; // Use external ID for network communication
message.state = job.state;
message.ver = job.ver;
message.utc = Util.nowUnixSecondsUtc();