diff options
-rw-r--r-- | dive.h | 3 | ||||
-rw-r--r-- | file.c | 25 | ||||
-rw-r--r-- | parse-xml.c | 104 |
3 files changed, 129 insertions, 3 deletions
@@ -644,7 +644,8 @@ extern void parse_xml_buffer(const char *url, const char *buf, int size, struct extern void parse_xml_exit(void); extern void set_filename(const char *filename, bool force); -extern int parse_dm4_buffer(const sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table, char **error); +extern int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table, char **error); +extern int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char *buf, int size, struct dive_table *table, char **error); extern void parse_file(const char *filename, char **error); extern void parse_csv_file(const char *filename, int time, int depth, int temp, int po2f, int cnsf, int stopdepthf, int sepidx, const char *csvtemplate, char **error); @@ -151,9 +151,17 @@ static int try_to_xslt_open_csv(const char *filename, struct memblock *mem, char return 0; } +int db_test_func(void *param, int columns, char **data, char **column) +{ + return *data[0] == '0'; +} + + static int try_to_open_db(const char *filename, struct memblock *mem, char **error) { sqlite3 *handle; + char dm4_test[] = "select count(*) from sqlite_master where type='table' and name='Dive' and sql like '%ProfileBlob%'"; + char shearwater_test[] = "select count(*) from sqlite_master where type='table' and name='system' and sql like '%dbVersion%'"; int retval; retval = sqlite3_open(filename, &handle); @@ -163,7 +171,22 @@ static int try_to_open_db(const char *filename, struct memblock *mem, char **err return 1; } - retval = parse_dm4_buffer(handle, filename, mem->buffer, mem->size, &dive_table, error); + /* Testing if DB schema resembles Suunto DM4 database format */ + retval = sqlite3_exec(handle, dm4_test, &db_test_func, 0, NULL); + if (!retval) { + retval = parse_dm4_buffer(handle, filename, mem->buffer, mem->size, &dive_table, error); + sqlite3_close(handle); + return retval; + } + + /* Testing if DB schema resembles Shearwater database format */ + retval = sqlite3_exec(handle, shearwater_test, &db_test_func, 0, NULL); + if (!retval) { + retval = parse_shearwater_buffer(handle, filename, mem->buffer, mem->size, &dive_table, error); + sqlite3_close(handle); + return retval; + } + sqlite3_close(handle); return retval; diff --git a/parse-xml.c b/parse-xml.c index 60a13c336..b93906f55 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -18,6 +18,7 @@ #include "device.h" int verbose, quit; +int metric = 1; static xmlDoc *test_xslt_transforms(xmlDoc *doc, const char **params, char **error); @@ -1861,7 +1862,7 @@ extern int dm4_dive(void *param, int columns, char **data, char **column) return SQLITE_OK; } -int parse_dm4_buffer(const sqlite3 *handle, const char *url, const char *buffer, int size, +int parse_dm4_buffer(sqlite3 *handle, const char *url, const char *buffer, int size, struct dive_table *table, char **error) { int retval; @@ -1882,6 +1883,107 @@ int parse_dm4_buffer(const sqlite3 *handle, const char *url, const char *buffer, return 0; } +extern int shearwater_profile_sample(void *handle, int columns, char **data, char **column) +{ + sample_start(); + if (data[0]) + cur_sample->time.seconds = atoi(data[0]); + if (data[1]) + cur_sample->depth.mm = metric ? atof(data[1]) * 1000 : feet_to_mm(atof(data[1])); + if (data[2]) + cur_sample->temperature.mkelvin = metric ? C_to_mkelvin(atof(data[2])) : F_to_mkelvin(atof(data[2])); + + /* We don't actually have data[3], but it should appear in the + * SQL query at some point. + if (data[3]) + cur_sample->cylinderpressure.mbar = metric ? atoi(data[3]) * 1000 : psi_to_mbar(atoi(data[3])); + */ + sample_end(); + + return 0; +} + +extern int shearwater_dive(void *param, int columns, char **data, char **column) +{ + int i, interval, retval = 0; + sqlite3 *handle = (sqlite3 *)param; + float *profileBlob; + unsigned char *tempBlob; + char *err = NULL; + char *location, *site; + char get_profile_template[] = "select currentTime,currentDepth,waterTemp from dive_log_records where diveLogId = %d"; + char get_tags_template[] = "select Text from DiveTag where DiveId = %d"; + char get_profile_sample[128]; + + dive_start(); + cur_dive->number = atoi(data[0]); + + cur_dive->when = (time_t)(atol(data[1])); + + if (data[2]) + utf8_string(data[2], &cur_dive->location); + if (data[3]) + utf8_string(data[3], &cur_dive->buddy); + if (data[4]) + utf8_string(data[4], &cur_dive->notes); + + metric = atoi(data[5]) == 1 ? 0 : 1; + + /* TODO: verify that metric calculation is correct */ + if (data[6]) + cur_dive->dc.maxdepth.mm = metric ? atof(data[6]) * 1000 : feet_to_mm(atof(data[6])); + + if (data[7]) + cur_dive->dc.duration.seconds = atoi(data[7]) * 60; + + if (data[8]) + cur_dive->dc.surface_pressure.mbar = atoi(data[8]); + /* + * TODO: the deviceid hash should be calculated here. + */ + settings_start(); + dc_settings_start(); + if (data[9]) + utf8_string(data[9], &cur_settings.dc.serial_nr); + if (data[10]) + utf8_string(data[10], &cur_settings.dc.model); + + cur_settings.dc.deviceid = 0xffffffff; + dc_settings_end(); + settings_end(); + + snprintf(get_profile_sample, sizeof(get_profile_sample) - 1, get_profile_template, cur_dive->number); + retval = sqlite3_exec(handle, get_profile_sample, &shearwater_profile_sample, 0, &err); + if (retval != SQLITE_OK) { + fprintf(stderr, "%s", translate("gettextFromC","Database query get_profile_sample failed.\n")); + return 1; + } + + dive_end(); + + return SQLITE_OK; +} + + +int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char *buffer, int size, + struct dive_table *table, char **error) +{ + int retval; + char *err = NULL; + target_table = table; + + char get_dives[] = "select i.diveId,timestamp,location||' / '||site,buddy,notes,imperialUnits,maxDepth,maxTime,startSurfacePressure,computerSerial,computerModel FROM dive_info AS i JOIN dive_logs AS l ON i.diveId=l.diveId"; + + retval = sqlite3_exec(handle, get_dives, &shearwater_dive, handle, &err); + + if (retval != SQLITE_OK) { + fprintf(stderr, translate("gettextFromC","Database query failed '%s'.\n"), url); + return 1; + } + + return 0; +} + void parse_xml_init(void) { LIBXML_TEST_VERSION |