Dive site: set UUID only on save or load

Since the UUID will be overwritten on save and is only used on save
and load, set it only on save or load. For other created dive sites,
leave the UUID field uninitialized.

This means that the UUID will change between saves. Let's see how
the git saver handles that.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2019-03-03 18:39:12 +01:00 committed by Dirk Hohndel
parent ac1602f512
commit 31291b1c56
16 changed files with 40 additions and 65 deletions

View file

@ -196,7 +196,7 @@ static unsigned char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive
ds = get_dive_site_by_name(buffer, sites); ds = get_dive_site_by_name(buffer, sites);
dt_dive->dive_site = ds; dt_dive->dive_site = ds;
if (!dt_dive->dive_site) if (!dt_dive->dive_site)
dt_dive->dive_site = create_dive_site(buffer, dt_dive->when, sites); dt_dive->dive_site = create_dive_site(buffer, sites);
free(locality); free(locality);
locality = NULL; locality = NULL;
free(dive_point); free(dive_point);

View file

@ -4033,7 +4033,7 @@ static void dive_set_geodata_from_picture(struct dive *dive, struct picture *pic
if (ds) { if (ds) {
ds->location = picture->location; ds->location = picture->location;
} else { } else {
dive->dive_site = create_dive_site_with_gps("", &picture->location, dive->when, table); dive->dive_site = create_dive_site_with_gps("", &picture->location, table);
invalidate_dive_cache(dive); invalidate_dive_cache(dive);
} }
} }

View file

@ -143,7 +143,7 @@ struct dive_site *alloc_dive_site()
return ds; return ds;
} }
/* we never allow a second dive site with the same uuid */ /* when parsing, dive sites are identified by uuid */
struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table) struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table)
{ {
struct dive_site *ds; struct dive_site *ds;
@ -229,44 +229,27 @@ void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table)
free_dive_site(ds); free_dive_site(ds);
} }
static uint32_t create_divesite_uuid(const char *name, timestamp_t divetime)
{
if (name == NULL)
name ="";
union {
unsigned char hash[20];
uint32_t i;
} u;
SHA_CTX ctx;
SHA1_Init(&ctx);
SHA1_Update(&ctx, &divetime, sizeof(timestamp_t));
SHA1_Update(&ctx, name, strlen(name));
SHA1_Final(u.hash, &ctx);
// now return the first 32 of the 160 bit hash
return u.i;
}
/* allocate a new site and add it to the table */ /* allocate a new site and add it to the table */
struct dive_site *create_dive_site(const char *name, timestamp_t divetime, struct dive_site_table *ds_table) struct dive_site *create_dive_site(const char *name, struct dive_site_table *ds_table)
{ {
uint32_t uuid = create_divesite_uuid(name, divetime); struct dive_site *ds = alloc_dive_site();
struct dive_site *ds = alloc_or_get_dive_site(uuid, ds_table);
ds->name = copy_string(name); ds->name = copy_string(name);
add_dive_site_to_table(ds, ds_table);
return ds; return ds;
} }
/* same as before, but with GPS data */ /* same as before, but with GPS data */
struct dive_site *create_dive_site_with_gps(const char *name, const location_t *loc, timestamp_t divetime, struct dive_site_table *ds_table) struct dive_site *create_dive_site_with_gps(const char *name, const location_t *loc, struct dive_site_table *ds_table)
{ {
uint32_t uuid = create_divesite_uuid(name, divetime); struct dive_site *ds = alloc_dive_site();
struct dive_site *ds = alloc_or_get_dive_site(uuid, ds_table);
ds->name = copy_string(name); ds->name = copy_string(name);
ds->location = *loc; ds->location = *loc;
add_dive_site_to_table(ds, ds_table);
return ds; return ds;
} }
/* a uuid is always present - but if all the other fields are empty, the dive site is pointless */ /* if all fields are empty, the dive site is pointless */
bool dive_site_is_empty(struct dive_site *ds) bool dive_site_is_empty(struct dive_site *ds)
{ {
return !ds || return !ds ||
@ -286,7 +269,6 @@ void copy_dive_site(struct dive_site *orig, struct dive_site *copy)
copy->name = copy_string(orig->name); copy->name = copy_string(orig->name);
copy->notes = copy_string(orig->notes); copy->notes = copy_string(orig->notes);
copy->description = copy_string(orig->description); copy->description = copy_string(orig->description);
copy->uuid = orig->uuid;
copy_taxonomy(&orig->taxonomy, &copy->taxonomy); copy_taxonomy(&orig->taxonomy, &copy->taxonomy);
} }
@ -370,7 +352,7 @@ void merge_dive_sites(struct dive_site *ref, struct dive_site *dive_sites[], int
mark_divelist_changed(true); mark_divelist_changed(true);
} }
struct dive_site *find_or_create_dive_site_with_name(const char *name, timestamp_t divetime, struct dive_site_table *ds_table) struct dive_site *find_or_create_dive_site_with_name(const char *name, struct dive_site_table *ds_table)
{ {
int i; int i;
struct dive_site *ds; struct dive_site *ds;
@ -380,7 +362,7 @@ struct dive_site *find_or_create_dive_site_with_name(const char *name, timestamp
} }
if (ds) if (ds)
return ds; return ds;
return create_dive_site(name, divetime, ds_table); return create_dive_site(name, ds_table);
} }
void purge_empty_dive_sites(struct dive_site_table *ds_table) void purge_empty_dive_sites(struct dive_site_table *ds_table)

View file

@ -55,8 +55,8 @@ int nr_of_dives_at_dive_site(struct dive_site *ds, bool select_only);
bool is_dive_site_used(struct dive_site *ds, bool select_only); bool is_dive_site_used(struct dive_site *ds, bool select_only);
void free_dive_site(struct dive_site *ds); void free_dive_site(struct dive_site *ds);
void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table); void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table);
struct dive_site *create_dive_site(const char *name, timestamp_t divetime, struct dive_site_table *ds_table); struct dive_site *create_dive_site(const char *name, struct dive_site_table *ds_table);
struct dive_site *create_dive_site_with_gps(const char *name, const location_t *, timestamp_t divetime, struct dive_site_table *ds_table); struct dive_site *create_dive_site_with_gps(const char *name, const location_t *, struct dive_site_table *ds_table);
struct dive_site *get_dive_site_by_name(const char *name, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_name(const char *name, struct dive_site_table *ds_table);
struct dive_site *get_dive_site_by_gps(const location_t *, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_gps(const location_t *, struct dive_site_table *ds_table);
struct dive_site *get_dive_site_by_gps_and_name(char *name, const location_t *, struct dive_site_table *ds_table); struct dive_site *get_dive_site_by_gps_and_name(char *name, const location_t *, struct dive_site_table *ds_table);
@ -67,7 +67,7 @@ void copy_dive_site_taxonomy(struct dive_site *orig, struct dive_site *copy);
void copy_dive_site(struct dive_site *orig, struct dive_site *copy); void copy_dive_site(struct dive_site *orig, struct dive_site *copy);
void merge_dive_site(struct dive_site *a, struct dive_site *b); void merge_dive_site(struct dive_site *a, struct dive_site *b);
unsigned int get_distance(const location_t *loc1, const location_t *loc2); unsigned int get_distance(const location_t *loc1, const location_t *loc2);
struct dive_site *find_or_create_dive_site_with_name(const char *name, timestamp_t divetime, struct dive_site_table *ds_table); struct dive_site *find_or_create_dive_site_with_name(const char *name, struct dive_site_table *ds_table);
void merge_dive_sites(struct dive_site *ref, struct dive_site *dive_sites[], int count); void merge_dive_sites(struct dive_site *ref, struct dive_site *dive_sites[], int count);
void purge_empty_dive_sites(struct dive_site_table *ds_table); void purge_empty_dive_sites(struct dive_site_table *ds_table);
void clear_dive_site_table(struct dive_site_table *ds_table); void clear_dive_site_table(struct dive_site_table *ds_table);

View file

@ -211,7 +211,7 @@ static void copy_gps_location(struct gpsTracker &gps, struct dive *d)
{ {
struct dive_site *ds = d->dive_site; struct dive_site *ds = d->dive_site;
if (!ds) { if (!ds) {
ds = create_dive_site(qPrintable(gps.name), gps.when, &dive_site_table); ds = create_dive_site(qPrintable(gps.name), &dive_site_table);
d->dive_site = ds; d->dive_site = ds;
} }
ds->location = gps.location; ds->location = gps.location;

View file

@ -197,7 +197,7 @@ static int cobalt_dive(void *param, int columns, char **data, char **column)
return 1; return 1;
} }
sprintf(tmp, "%s / %s", location, location_site); sprintf(tmp, "%s / %s", location, location_site);
state->cur_dive->dive_site = find_or_create_dive_site_with_name(tmp, state->cur_dive->when, state->sites); state->cur_dive->dive_site = find_or_create_dive_site_with_name(tmp, state->sites);
free(tmp); free(tmp);
} }
free(location); free(location);

View file

@ -287,7 +287,7 @@ static int divinglog_dive(void *param, int columns, char **data, char **column)
state->cur_dive->when = (time_t)(atol(data[1])); state->cur_dive->when = (time_t)(atol(data[1]));
if (data[2]) if (data[2])
state->cur_dive->dive_site = find_or_create_dive_site_with_name(data[2], state->cur_dive->when, state->sites); state->cur_dive->dive_site = find_or_create_dive_site_with_name(data[2], state->sites);
if (data[3]) if (data[3])
utf8_string(data[3], &state->cur_dive->buddy); utf8_string(data[3], &state->cur_dive->buddy);

View file

@ -596,7 +596,7 @@ static void parse_string_field(device_data_t *devdata, struct dive *dive, dc_fie
parse_location(line, &location); parse_location(line, &location);
if (location.lat.udeg && location.lon.udeg) if (location.lat.udeg && location.lon.udeg)
dive->dive_site = create_dive_site_with_gps(str->value, &location, time(NULL), devdata->sites); dive->dive_site = create_dive_site_with_gps(str->value, &location, devdata->sites);
} }
} }
#endif #endif

View file

@ -143,7 +143,6 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
while (ptr < buf_size) { while (ptr < buf_size) {
int i; int i;
bool found_divesite = false;
dive = alloc_dive(); dive = alloc_dive();
memset(&sensor_ids, 0, sizeof(sensor_ids)); memset(&sensor_ids, 0, sizeof(sensor_ids));
dc = &dive->dc; dc = &dive->dc;
@ -191,8 +190,10 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
} }
/* Store the location only if we have one */ /* Store the location only if we have one */
if (len || place_len) if (len || place_len) {
found_divesite = true; dive->dive_site = find_or_create_dive_site_with_name(location, sites);
free(location);
}
ptr += len + 4 + place_len; ptr += len + 4 + place_len;
@ -224,12 +225,6 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
dive->when = array_uint32_le(buf + ptr); dive->when = array_uint32_le(buf + ptr);
ptr += 4; ptr += 4;
// now that we have the dive time we can store the divesite
// (we need the dive time to create deterministic uuids)
if (found_divesite) {
dive->dive_site = find_or_create_dive_site_with_name(location, dive->when, sites);
free(location);
}
//unsigned int end_time = array_uint32_le(buf + ptr); //unsigned int end_time = array_uint32_le(buf + ptr);
ptr += 4; ptr += 4;

View file

@ -159,7 +159,7 @@ static void parse_dive_gps(char *line, struct membuffer *str, void *_dive)
if (!ds) { if (!ds) {
ds = get_dive_site_by_gps(&location, &dive_site_table); ds = get_dive_site_by_gps(&location, &dive_site_table);
if (!ds) if (!ds)
dive->dive_site = create_dive_site_with_gps("", &location, dive->when, &dive_site_table); dive->dive_site = create_dive_site_with_gps("", &location, &dive_site_table);
else else
dive->dive_site = ds; dive->dive_site = ds;
} else { } else {
@ -183,7 +183,7 @@ static void parse_dive_location(char *line, struct membuffer *str, void *_dive)
if (!ds) { if (!ds) {
ds = get_dive_site_by_name(name, &dive_site_table); ds = get_dive_site_by_name(name, &dive_site_table);
if (!ds) if (!ds)
dive->dive_site = create_dive_site(name, dive->when, &dive_site_table); dive->dive_site = create_dive_site(name, &dive_site_table);
else else
dive->dive_site = ds; dive->dive_site = ds;
} else { } else {

View file

@ -985,7 +985,7 @@ static void divinglog_place(char *place, struct dive_site **ds, struct parser_st
state->country ? state->country : ""); state->country ? state->country : "");
*ds = get_dive_site_by_name(buffer, state->sites); *ds = get_dive_site_by_name(buffer, state->sites);
if (!*ds) if (!*ds)
*ds = create_dive_site(buffer, state->cur_dive->when, state->sites); *ds = create_dive_site(buffer, state->sites);
// TODO: capture the country / city info in the taxonomy instead // TODO: capture the country / city info in the taxonomy instead
free(state->city); free(state->city);
@ -1137,7 +1137,7 @@ static void gps_lat(char *buffer, struct dive *dive, struct parser_state *state)
location.lat = parse_degrees(buffer, &end); location.lat = parse_degrees(buffer, &end);
if (!ds) { if (!ds) {
dive->dive_site = create_dive_site_with_gps(NULL, &location, dive->when, state->sites); dive->dive_site = create_dive_site_with_gps(NULL, &location, state->sites);
} else { } else {
if (ds->location.lat.udeg && ds->location.lat.udeg != location.lat.udeg) if (ds->location.lat.udeg && ds->location.lat.udeg != location.lat.udeg)
fprintf(stderr, "Oops, changing the latitude of existing dive site id %8x name %s; not good\n", ds->uuid, ds->name ?: "(unknown)"); fprintf(stderr, "Oops, changing the latitude of existing dive site id %8x name %s; not good\n", ds->uuid, ds->name ?: "(unknown)");
@ -1153,7 +1153,7 @@ static void gps_long(char *buffer, struct dive *dive, struct parser_state *state
location.lon = parse_degrees(buffer, &end); location.lon = parse_degrees(buffer, &end);
if (!ds) { if (!ds) {
dive->dive_site = create_dive_site_with_gps(NULL, &location, dive->when, state->sites); dive->dive_site = create_dive_site_with_gps(NULL, &location, state->sites);
} else { } else {
if (ds->location.lon.udeg && ds->location.lon.udeg != location.lon.udeg) if (ds->location.lon.udeg && ds->location.lon.udeg != location.lon.udeg)
fprintf(stderr, "Oops, changing the longitude of existing dive site id %8x name %s; not good\n", ds->uuid, ds->name ?: "(unknown)"); fprintf(stderr, "Oops, changing the longitude of existing dive site id %8x name %s; not good\n", ds->uuid, ds->name ?: "(unknown)");
@ -1191,7 +1191,7 @@ static void gps_in_dive(char *buffer, struct dive *dive, struct parser_state *st
state->cur_location = location; state->cur_location = location;
dive->dive_site = ds; dive->dive_site = ds;
} else { } else {
dive->dive_site = create_dive_site_with_gps("", &location, dive->when, state->sites); dive->dive_site = create_dive_site_with_gps("", &location, state->sites);
} }
} else { } else {
if (dive_site_has_gps_location(ds) && if (dive_site_has_gps_location(ds) &&
@ -2122,7 +2122,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct dive_table *tabl
/* Measure GPS */ /* Measure GPS */
state.cur_location.lat.udeg = (int)((ptr[7] << 24) + (ptr[6] << 16) + (ptr[5] << 8) + (ptr[4] << 0)); state.cur_location.lat.udeg = (int)((ptr[7] << 24) + (ptr[6] << 16) + (ptr[5] << 8) + (ptr[4] << 0));
state.cur_location.lon.udeg = (int)((ptr[11] << 24) + (ptr[10] << 16) + (ptr[9] << 8) + (ptr[8] << 0)); state.cur_location.lon.udeg = (int)((ptr[11] << 24) + (ptr[10] << 16) + (ptr[9] << 8) + (ptr[8] << 0));
state.cur_dive->dive_site = create_dive_site_with_gps("DLF imported", &state.cur_location, state.cur_dive->when, state.sites); state.cur_dive->dive_site = create_dive_site_with_gps("DLF imported", &state.cur_location, state.sites);
break; break;
default: default:
break; break;

View file

@ -434,7 +434,7 @@ void add_dive_site(char *ds_name, struct dive *dive, struct parser_state *state)
if (exact_match) { if (exact_match) {
dive->dive_site = exact_match; dive->dive_site = exact_match;
} else { } else {
struct dive_site *newds = create_dive_site(buffer, dive->when, state->sites); struct dive_site *newds = create_dive_site(buffer, state->sites);
dive->dive_site = newds; dive->dive_site = newds;
if (has_location(&state->cur_location)) { if (has_location(&state->cur_location)) {
// we started this uuid with GPS data, so lets use those // we started this uuid with GPS data, so lets use those
@ -449,7 +449,7 @@ void add_dive_site(char *ds_name, struct dive *dive, struct parser_state *state)
dive->dive_site = ds; dive->dive_site = ds;
} }
} else { } else {
dive->dive_site = create_dive_site(buffer, dive->when, state->sites); dive->dive_site = create_dive_site(buffer, state->sites);
} }
} }
free(to_free); free(to_free);

View file

@ -993,7 +993,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, char *
} else if (!is_log && dive && !strcmp(tag, "divespot_id")) { } else if (!is_log && dive && !strcmp(tag, "divespot_id")) {
int divespot_id = atoi(val); int divespot_id = atoi(val);
if (divespot_id != -1) { if (divespot_id != -1) {
struct dive_site *ds = create_dive_site("from Uemis", dive->when, devdata->sites); struct dive_site *ds = create_dive_site("from Uemis", devdata->sites);
dive->dive_site = ds; dive->dive_site = ds;
uemis_mark_divelocation(dive->dc.diveid, divespot_id, ds); uemis_mark_divelocation(dive->dc.diveid, divespot_id, ds);
} }

View file

@ -658,17 +658,15 @@ struct dive_site *MainTab::updateDiveSite(struct dive_site *pickedDs, dive *d)
if (pickedDs == RECENTLY_ADDED_DIVESITE) { if (pickedDs == RECENTLY_ADDED_DIVESITE) {
QString name = ui.location->text(); QString name = ui.location->text();
pickedDs = create_dive_site(qPrintable(name), displayed_dive.when, &dive_site_table); pickedDs = create_dive_site(qPrintable(name), &dive_site_table);
createdNewDive = true; createdNewDive = true;
} }
if (origDs) { if (origDs) {
if(createdNewDive) { if(createdNewDive) {
uint32_t pickedUuid = pickedDs->uuid;
copy_dive_site(origDs, pickedDs); copy_dive_site(origDs, pickedDs);
free(pickedDs->name); free(pickedDs->name);
pickedDs->name = copy_qstring(ui.location->text()); pickedDs->name = copy_qstring(ui.location->text());
pickedDs->uuid = pickedUuid;
qDebug() << "Creating and copying dive site"; qDebug() << "Creating and copying dive site";
} else if (!has_location(&pickedDs->location)) { } else if (!has_location(&pickedDs->location)) {
pickedDs->location = origDs->location; pickedDs->location = origDs->location;

View file

@ -774,7 +774,7 @@ static void setupDivesite(struct dive *d, struct dive_site *ds, double lat, doub
if (ds) { if (ds) {
ds->location = location; ds->location = location;
} else { } else {
d->dive_site = create_dive_site_with_gps(locationtext, &location, d->when, &dive_site_table); d->dive_site = create_dive_site_with_gps(locationtext, &location, &dive_site_table);
} }
} }
@ -892,7 +892,7 @@ bool QMLManager::checkLocation(DiveObjectHelper *myDive, struct dive *d, QString
diveChanged = true; diveChanged = true;
ds = get_dive_site_by_name(qPrintable(location), &dive_site_table); ds = get_dive_site_by_name(qPrintable(location), &dive_site_table);
if (!ds && !location.isEmpty()) if (!ds && !location.isEmpty())
ds = create_dive_site(qPrintable(location), d->when, &dive_site_table); ds = create_dive_site(qPrintable(location), &dive_site_table);
d->dive_site = ds; d->dive_site = ds;
} }
// now make sure that the GPS coordinates match - if the user changed the name but not // now make sure that the GPS coordinates match - if the user changed the name but not

View file

@ -315,7 +315,7 @@ static void smtk_wreck_site(MdbHandle *mdb, char *site_idx, struct dive_site *ds
* Location format: * Location format:
* | Idx | Text | Province | Country | Depth | * | Idx | Text | Province | Country | Depth |
*/ */
static void smtk_build_location(MdbHandle *mdb, char *idx, timestamp_t when, struct dive_site **location) static void smtk_build_location(MdbHandle *mdb, char *idx, struct dive_site **location)
{ {
MdbTableDef *table; MdbTableDef *table;
MdbColumn *col[MDB_MAX_COLS]; MdbColumn *col[MDB_MAX_COLS];
@ -376,9 +376,9 @@ static void smtk_build_location(MdbHandle *mdb, char *idx, timestamp_t when, str
ds = get_dive_site_by_name(str, &dive_site_table); ds = get_dive_site_by_name(str, &dive_site_table);
if (!ds) { if (!ds) {
if (!has_location(&loc)) if (!has_location(&loc))
ds = create_dive_site(str, when, &dive_site_table); ds = create_dive_site(str, &dive_site_table);
else else
ds = create_dive_site_with_gps(str, &loc, when, &dive_site_table); ds = create_dive_site_with_gps(str, &loc, &dive_site_table);
} }
*location = ds; *location = ds;
smtk_free(bound_values, table->num_cols); smtk_free(bound_values, table->num_cols);
@ -1063,7 +1063,7 @@ void smartrak_import(const char *file, struct dive_table *divetable)
smtkdive->visibility = strtod(col[coln(VISIBILITY)]->bind_ptr, NULL) > 25 ? 5 : lrint(strtod(col[13]->bind_ptr, NULL) / 5); smtkdive->visibility = strtod(col[coln(VISIBILITY)]->bind_ptr, NULL) > 25 ? 5 : lrint(strtod(col[13]->bind_ptr, NULL) / 5);
smtkdive->weightsystem[0].weight.grams = lrint(strtod(col[coln(WEIGHT)]->bind_ptr, NULL) * 1000); smtkdive->weightsystem[0].weight.grams = lrint(strtod(col[coln(WEIGHT)]->bind_ptr, NULL) * 1000);
smtkdive->suit = copy_string(suit_list[atoi(col[coln(SUITIDX)]->bind_ptr) - 1]); smtkdive->suit = copy_string(suit_list[atoi(col[coln(SUITIDX)]->bind_ptr) - 1]);
smtk_build_location(mdb_clon, col[coln(SITEIDX)]->bind_ptr, smtkdive->when, &smtkdive->dive_site); smtk_build_location(mdb_clon, col[coln(SITEIDX)]->bind_ptr, &smtkdive->dive_site);
smtkdive->buddy = smtk_locate_buddy(mdb_clon, col[0]->bind_ptr, buddy_list); smtkdive->buddy = smtk_locate_buddy(mdb_clon, col[0]->bind_ptr, buddy_list);
smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Type", "TypeRelation", type_list, true); smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Type", "TypeRelation", type_list, true);
smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Activity", "ActivityRelation", activity_list, false); smtk_parse_relations(mdb_clon, smtkdive, col[0]->bind_ptr, "Activity", "ActivityRelation", activity_list, false);