Changesets are also output, updating help text.
[planetdump.git] / users.cpp
1 #include "users.hpp"
2 #include <sstream>
3 #include <cstdlib>
4 #include <cassert>
5 #include <cstring>
6
7 extern "C" {
8 // for xmlescape:
9 #include "output_osm.h" 
10 }
11
12 using namespace std;
13 using namespace pqxx;
14
15 static char **user_list;
16 static unsigned long max_uid;
17
18 const char *lookup_user(const char *s) {
19   unsigned long int user_id = strtoul(s, NULL, 10);
20   const char *user = (user_id >= 0 && user_id <= max_uid) ? user_list[user_id] : "";
21   return user ? user : "";
22 }
23
24 unsigned long int max_userid(pqxx::work &xaction) {
25   const char *sql = "SELECT MAX(id) FROM users";
26   unsigned long int max = 0;
27
28   pqxx::result res = xaction.exec(sql);
29
30   if (!res[0][0].to<unsigned long int>(max)) {
31     throw std::runtime_error("Max user ID is not numeric. "
32                              "Maybe the users table is empty?");
33   }
34
35   return max;
36 }
37
38 void fetch_users(pqxx::work &xaction)
39 {
40   char tmp[1024];
41   max_uid = max_userid(xaction);
42
43   user_list = (char **)calloc(max_uid + 1, sizeof(char *));
44   if (!user_list) {
45     ostringstream ostr;
46     ostr << "Malloc of user_list failed for " << max_uid << " users\n";
47     throw std::runtime_error(ostr.str());
48   }
49
50   ostringstream query;
51   query << "SELECT id,display_name from users where id <= " << max_uid
52         << " and data_public = true";
53   
54   icursorstream users(xaction, query.str(), "fetch_users", 1000);
55   
56   const icursor_iterator ic_end;
57   for (icursor_iterator ic_itr(users); ic_itr != ic_end; ++ic_itr) {
58     const pqxx::result &res = *ic_itr;
59     for (pqxx::result::const_iterator itr = res.begin();
60          itr != res.end(); ++itr) {
61       unsigned long int id;
62       string display_name;
63
64       if (!(*itr)[0].to<unsigned long int>(id)) {
65         throw std::runtime_error("User ID is not numeric.");
66       }
67       if (!(*itr)[1].to<string>(display_name)) {
68         throw std::runtime_error("Could not get user display name.");
69       }
70
71       assert(id <= max_uid);
72       snprintf(tmp, sizeof(tmp), " user=\"%s\" uid=\"%lu\"", 
73                xmlescape(display_name.c_str()), id);
74       user_list[id] = strdup(tmp);
75       assert(user_list[id]);
76     }
77   }
78 }
79
80 void free_users(void) {
81   for(unsigned long i=0; i<=max_uid; i++)
82     free(user_list[i]);
83   free(user_list);
84 }