#include #include #include #include #include #include /* * Program to export Sputnik data from PostgreSQL database into binary file. * Exports tuples with calculated id column. */ typedef struct { u_int32_t timestamp; u_int32_t station; u_int32_t id, garbage2; u_int8_t size, protocol; u_int8_t flags; u_int8_t strength; u_int32_t seqno; } __attribute__ ((packed)) beacon_log_t; #define BUTTON 0x02 int main(int argc, char *argv[]) { FILE *f = NULL; int M, N, i; beacon_log_t b; PGconn *connection; PGresult *result = NULL; int idNo, sequenceNo, epochNo, addressNo, strengthNo, tagsNo; char *id, *sequence, *epoch, *address, *strength, *tags; struct in_addr station; b.garbage2 = 0; b.size = 0x10; b.protocol = 0x17; M = 0; connection = PQconnectdb("dbname = tomus"); if (NULL == connection) { return EXIT_FAILURE; } if (CONNECTION_OK != PQstatus(connection)) { printf("%s", PQerrorMessage(connection)); PQfinish(connection); connection = NULL; return EXIT_FAILURE; } result = PQexec(connection, "begin"); PQclear(result); result = PQexec(connection, "DECLARE export CURSOR FOR " " SELECT sputnik.id AS id, sequence, time, " " extract('epoch' from time) AS epoch, address, strength, tags " " FROM sputnik.sputnik INNER JOIN sputnik.station ON sputnik.station = station.id " " WHERE sputnik.id IS NOT NULL ORDER BY time, sputnik.id, station.id "); if (PGRES_COMMAND_OK != PQresultStatus(result)) { printf("%s", PQerrorMessage(connection)); PQclear(result); result = PQexec(connection, "end"); PQclear(result); PQfinish(connection); connection = NULL; return EXIT_FAILURE; } f = fopen(argv[1], "wb"); while (1) { result = PQexec(connection, "FETCH NEXT IN export"); if (PGRES_TUPLES_OK != PQresultStatus(result)) { fclose(f); printf("%s", PQerrorMessage(connection)); PQclear(result); result = PQexec(connection, "end"); PQclear(result); PQfinish(connection); connection = NULL; return EXIT_FAILURE; } N = PQntuples(result); if (0 == N) { break; } M += N; idNo = PQfnumber(result, "id"); sequenceNo = PQfnumber(result, "sequence"); epochNo = PQfnumber(result, "epoch"); addressNo = PQfnumber(result, "address"); strengthNo = PQfnumber(result, "strength"); tagsNo = PQfnumber(result, "tags"); for (i = 0; i < N; ++i) { id = PQgetvalue(result, i, idNo); b.id = htonl(strtoul(id, NULL, 10)); sequence = PQgetvalue(result, i, sequenceNo); b.seqno = htonl(strtol(sequence, NULL, 10)); epoch = PQgetvalue(result, i, epochNo); b.timestamp = htonl(strtoul(epoch, NULL, 10)); address = PQgetvalue(result, i, addressNo); inet_aton(address, &station); b.station = htonl(station.s_addr); b.garbage2 = station.s_addr; strength = PQgetvalue(result, i, strengthNo); b.strength = strtoul(strength, NULL, 10); tags = PQgetvalue(result, i, tagsNo); b.flags = (strlen(tags)) ? BUTTON : 0; fwrite(&b, 1, sizeof(beacon_log_t), f); } PQclear(result); } fclose(f); result = PQexec(connection, "CLOSE export"); PQclear(result); result = PQexec(connection, "end"); PQclear(result); PQfinish(connection); connection = NULL; printf("Exported %i tuples.\n", M); return EXIT_SUCCESS; }