@@ -39,7 +39,7 @@ class SynchControl {
3939 static final long synch_upload_look_back_ms = 15 * 24 * 3600000L ; // period in past to check for upload
4040 static final long surely_newer_after_ms = 60000L ; // one-minute time difference accepted for timestamps server <-> client
4141
42- private static final int SYNCHERRORS_LOG_MAX_SIZE = 200000 ; //200 kb.
42+ private static final int SYNCHERRORS_LOG_MAX_SIZE = 10 * 1024 * 1024 ; // During upload sync only last 200kb are transferred, see TextResource
4343 private static final String FILENAME_PREVIOUS_SUFFIX = ".previous.log" ;
4444
4545 long lastSynchStartedMillis ;
@@ -96,20 +96,22 @@ private void logSynchMessage(String logMessage, String tablename, DataKey dataKe
9696 File synchErrorsFile = new File (path );
9797
9898 Boolean appendLine =true ;
99-
100- //synchErrors.log rotation: if >5 Mb, delete old synchErrors.previous.log file and rename synchErrors.log to synchErrors.log.previous.log
101- if (synchErrorsFile .length () > SYNCHERRORS_LOG_MAX_SIZE ) {
102- File oldPreviousLogfile =new File (path + FILENAME_PREVIOUS_SUFFIX );
103-
104- // rotate existing efacloud.log to efacloud.log.previous and delete the existing file if necessary.
105- if ((oldPreviousLogfile .exists () && oldPreviousLogfile .delete ())
106- || (!oldPreviousLogfile .exists ())) {
107- if (synchErrorsFile .renameTo (new File (path + FILENAME_PREVIOUS_SUFFIX ))) {
108- appendLine =false ;
109- }
110- }
99+ if (isError ) {
100+ //log rotation only if we write to synchError.log
101+ //synchErrors.log rotation: if >5 Mb, delete old synchErrors.previous.log file and rename synchErrors.log to synchErrors.log.previous.log
102+ if (synchErrorsFile .length () > SYNCHERRORS_LOG_MAX_SIZE ) {
103+ File oldPreviousLogfile =new File (path + FILENAME_PREVIOUS_SUFFIX );
104+
105+ // rotate existing efacloud.log to efacloud.log.previous and delete the existing file if necessary.
106+ if ((oldPreviousLogfile .exists () && oldPreviousLogfile .delete ())
107+ || (!oldPreviousLogfile .exists ())) {
108+ if (synchErrorsFile .renameTo (new File (path + FILENAME_PREVIOUS_SUFFIX ))) {
109+ appendLine =false ;
110+ }
111+ }
112+ }
111113 }
112-
114+ // write to logfile, either synchError or efacloud.log
113115 TextResource .writeContents (path , dateString , appendLine );
114116 }
115117
@@ -154,13 +156,16 @@ void startSynchProcess(int synch_request) {
154156 }
155157
156158 /**
157- * In case an EntryId of a logbook entry is corrected, ensure that also the boat status is updated. Only by that
158- * update it is ensured the trip can be closed later.
159+ * In case an EntryId of a logbook entry is corrected, ensure that also the boat status is updated.
160+ * Only by that update it is ensured the trip can be closed later.
161+ *
162+ * The boat status only gets updated if the boat status points to the same logbook as the logbookrecord
163+ * which got a new entryID.
159164 *
160165 * @param boatId The UUID of the boat in the boat status
161166 * @param fixedEntryNo new EntryId for this boat status
162167 */
163- protected void adjustBoatStatus (UUID boatId , int fixedEntryNo ) {
168+ protected void adjustBoatStatus (UUID boatId , int oldEntryNo , String oldLogbookName , int fixedEntryNo ) {
164169 EfaCloudStorage boatstatus = Daten .tableBuilder .getPersistence ("efa2boatstatus" );
165170 DataKeyIterator it ;
166171 try {
@@ -170,12 +175,17 @@ protected void adjustBoatStatus(UUID boatId, int fixedEntryNo) {
170175 BoatStatusRecord bsr = (BoatStatusRecord ) boatstatus .get (boatstatuskey );
171176 if (bsr .getBoatId () != null ) {
172177 if (bsr .getBoatId ().compareTo (boatId ) == 0 ) {
173- bsr .setEntryNo (new DataTypeIntString ("" + fixedEntryNo ));
174- long globalLock = boatstatus .acquireGlobalLock ();
175- boatstatus .update (bsr , globalLock );
176- boatstatus .releaseGlobalLock (globalLock );
177- logSynchMessage (International .getString ("Korrigiere EntryNo in BoatStatus" ), "efa2boatstatus" ,
178- boatstatuskey , false );
178+ //Only update the boatstatusrecord if it points to the same logbook as
179+ //the record which got a new entryID.
180+ if (bsr .getLogbook ().equalsIgnoreCase (oldLogbookName )) {
181+ bsr .setEntryNo (new DataTypeIntString ("" + fixedEntryNo ));
182+ long globalLock = boatstatus .acquireGlobalLock ();
183+ boatstatus .update (bsr , globalLock );
184+ boatstatus .releaseGlobalLock (globalLock );
185+ logSynchMessage (International .getString ("Korrigiere EntryNo in BoatStatus" ), "efa2boatstatus" ,
186+ boatstatuskey , false );
187+ }
188+
179189 }
180190 }
181191 boatstatuskey = it .getNext ();
@@ -450,16 +460,20 @@ void nextTableForUploadSynch(Transaction tx) {
450460 if (localLastModified > LastModifiedLimit )
451461 localRecordsToInsertAtServer .add (localRecord );
452462 } else if (localLastModified > serverRecord .getLastModified ()) {
453- String preUpdateRecordsCompareResult = "" ; // removed August 2024: preUpdateRecordsCompare(localRecord, serverRecord, tx.tablename);
454- if (!preUpdateRecordsCompareResult .isEmpty ())
455- localRecordsToUpdateAtServer .add (localRecord );
456- else {
463+ // removed August 2024: String preUpdateRecordsCompare(localRecord, serverRecord, tx.tablename);
464+ /* String preUpdateRecordsCompareResult = "";
465+ * if (!preUpdateRecordsCompareResult.isEmpty()) {
466+ * localRecordsToUpdateAtServer.add(localRecord);
467+ * } else {
468+ */
469+ // just get a comparison of the records so that we can log them and the user can actually have a hint what has changed.
470+ String preUpdateRecordsCompareResult = preUpdateRecordsCompare (localRecord , serverRecord , tx .tablename );
457471 logSynchMessage (International .getMessage (
458472 "Update-Konflikt bei Datensatz in der {type}-Synchronisation. Unterschiedlich sind: {fields}" ,
459473 "Upload" , preUpdateRecordsCompareResult ) +
460474 " " + International .getString ("Bitte bereinige den Datensatz manuell." ), tx .tablename ,
461475 toCheck , false );
462- }
476+ // }
463477 }
464478 toCheck = it .getNext ();
465479 }
@@ -498,5 +512,50 @@ void nextTableForUploadSynch(Transaction tx) {
498512 null , false );
499513 }
500514 }
515+
516+ /**
517+ * Compares two records and points out which fields differ from another.
518+ *
519+ * @param dr1 DataRecord one to compare
520+ * @param dr2 DataRecord two to compare
521+ * @param tablename the table name to look up how many fields may be different.
522+ * @return empty String, if the records are of the same type and differ in only a tolerable amount of data fields
523+ */
524+ private String preUpdateRecordsCompare (DataRecord dr1 , DataRecord dr2 , String tablename ) {
525+ if (!efaCloudRolleBths && !isBoathouseApp )
526+ return "" ;
527+ if ((dr1 == null ) || (dr2 == null ) || (dr1 .getClass () != dr2 .getClass ()))
528+ return "type mismatch" ;
529+ // if archiving is executed or an archived record is restored, do not check for mismatches
530+ // because the archived record stub will have all fields changed.
531+
532+ int diff = 0 ;
533+ StringBuilder fieldList = new StringBuilder ();
534+ for (String field : dr1 .getFields ()) {
535+ if (!field .equalsIgnoreCase ("ChangeCount" )
536+ && !field .equalsIgnoreCase ("LastModified" )
537+ && !field .equalsIgnoreCase ("LastModification" )) {
538+
539+ String f1Value = dr1 .getAsString (field );
540+ String f2Value = dr2 .getAsString (field );
541+
542+ if (f1Value == null ) {
543+ if (f2Value != null ) {
544+ fieldList .append (field ).append ("(null" ).append ("/" ).append (f2Value ).append (")" ).append (", " );
545+ diff ++;
546+ }
547+ } else if (f2Value == null ) {
548+ fieldList .append (field ).append ("(" ).append (f1Value ).append ("/null)" ).append (", " );
549+ diff ++;
550+ // Use String comparison as the compareTo() implementation throws to many different exceptions.
551+ } else if (!dr1 .getAsString (field ).equalsIgnoreCase (dr2 .getAsString (field ))) {
552+ fieldList .append (field ).append ("(" ).append (f1Value ).append ("/" ).append (f2Value ).append (", " );
553+ diff ++;
554+ }
555+ }
556+ }
557+
558+ return fieldList .toString ();
559+ }
501560
502561}
0 commit comments