liquid_feedback_core

diff lf_update_issue_order.c @ 410:d301dc24b25c

Proportional Runoff for issues both based on single areas and single units
author jbe
date Mon Oct 14 19:36:33 2013 +0200 (2013-10-14)
parents 5f24058af0b8
children 82387194519b
line diff
     1.1 --- a/lf_update_issue_order.c	Mon Oct 14 00:58:38 2013 +0200
     1.2 +++ b/lf_update_issue_order.c	Mon Oct 14 19:36:33 2013 +0200
     1.3 @@ -174,16 +174,11 @@
     1.4  }
     1.5  
     1.6  // write results to database:
     1.7 -static int write_ranks(PGconn *db, char *escaped_area_id) {
     1.8 +static int write_ranks(PGconn *db, char *escaped_area_or_unit_id, char *mode) {
     1.9    PGresult *res;
    1.10    char *cmd;
    1.11    int i;
    1.12 -  if (asprintf(&cmd, "BEGIN; DELETE FROM \"issue_order\" USING \"issue\" WHERE \"issue_order\".\"id\" = \"issue\".\"id\" AND \"issue\".\"area_id\" = %s", escaped_area_id) < 0) {
    1.13 -    fprintf(stderr, "Could not prepare query string in memory.\n");
    1.14 -    abort();
    1.15 -  }
    1.16 -  res = PQexec(db, cmd);
    1.17 -  free(cmd);
    1.18 +  res = PQexec(db, "BEGIN");
    1.19    if (!res) {
    1.20      fprintf(stderr, "Error in pqlib while sending SQL command to initiate issue order update.\n");
    1.21      return 1;
    1.22 @@ -204,7 +199,7 @@
    1.23        fprintf(stderr, "Could not escape literal in memory.\n");
    1.24        abort();
    1.25      }
    1.26 -    if (asprintf(&cmd, "INSERT INTO \"issue_order\" (\"id\", \"order_in_admission_state\", \"max_supporter_count\") SELECT %s, %i, max(\"supporter_count\") FROM \"initiative\" WHERE \"issue_id\" = %s", escaped_issue_id, candidates[i].seat, escaped_issue_id) < 0) {
    1.27 +    if (asprintf(&cmd, "UPDATE \"issue_order_in_admission_state\" SET \"order_in_%s\" = %i WHERE \"id\" = %s", mode, candidates[i].seat, escaped_issue_id) < 0) {
    1.28        fprintf(stderr, "Could not prepare query string in memory.\n");
    1.29        abort();
    1.30      }
    1.31 @@ -212,12 +207,12 @@
    1.32      res = PQexec(db, cmd);
    1.33      free(cmd);
    1.34      if (!res) {
    1.35 -      fprintf(stderr, "Error in pqlib while sending SQL command to insert issue order.\n");
    1.36 +      fprintf(stderr, "Error in pqlib while sending SQL command to update issue order.\n");
    1.37      } else if (
    1.38        PQresultStatus(res) != PGRES_COMMAND_OK &&
    1.39        PQresultStatus(res) != PGRES_TUPLES_OK
    1.40      ) {
    1.41 -      fprintf(stderr, "Error while executing SQL command to insert issue order:\n%s", PQresultErrorMessage(res));
    1.42 +      fprintf(stderr, "Error while executing SQL command to update issue order:\n%s", PQresultErrorMessage(res));
    1.43        PQclear(res);
    1.44      } else {
    1.45        PQclear(res);
    1.46 @@ -245,7 +240,7 @@
    1.47  }
    1.48  
    1.49  // calculate ordering of issues in admission state for an area and call write_ranks() to write it to database:
    1.50 -static int process_area(PGconn *db, PGresult *res, char *escaped_area_id) {
    1.51 +static int process_area_or_unit(PGconn *db, PGresult *res, char *escaped_area_or_unit_id, char *mode) {
    1.52    int err;                 // variable to store an error condition (0 = success)
    1.53    int ballot_count = 1;    // number of ballots, must be initiatized to 1, due to loop below
    1.54    struct ballot *ballots;  // data structure containing the ballots
    1.55 @@ -265,7 +260,7 @@
    1.56      if (!tuple_count) {
    1.57        // write results to database:
    1.58        if (logging) printf("No supporters for any issue. Writing ranks to database.\n");
    1.59 -      err = write_ranks(db, escaped_area_id);
    1.60 +      err = write_ranks(db, escaped_area_or_unit_id, mode);
    1.61        if (logging) printf("Done.\n");
    1.62        return 0;
    1.63      }
    1.64 @@ -377,7 +372,7 @@
    1.65  
    1.66    // write results to database:
    1.67    if (logging) printf("Writing ranks to database.\n");
    1.68 -  err = write_ranks(db, escaped_area_id);
    1.69 +  err = write_ranks(db, escaped_area_or_unit_id, mode);
    1.70    if (logging) printf("Done.\n");
    1.71  
    1.72    // free candidates[] array:
    1.73 @@ -445,6 +440,23 @@
    1.74      return 1;
    1.75    }
    1.76  
    1.77 +  // create missing "issue_order_in_admission_state" entries for issues
    1.78 +  res = PQexec(db, "INSERT INTO \"issue_order_in_admission_state\" (\"id\") SELECT \"issue\".\"id\" FROM \"issue\" NATURAL LEFT JOIN \"issue_order_in_admission_state\" WHERE \"issue\".\"state\" = 'admission'::\"issue_state\" AND \"issue_order_in_admission_state\".\"id\" ISNULL");
    1.79 +  if (!res) {
    1.80 +    fprintf(stderr, "Error in pqlib while sending SQL command creating new issue order entries.\n");
    1.81 +    err = 1;
    1.82 +  } else if (
    1.83 +    PQresultStatus(res) != PGRES_COMMAND_OK &&
    1.84 +    PQresultStatus(res) != PGRES_TUPLES_OK
    1.85 +  ) {
    1.86 +    fprintf(stderr, "Error while executing SQL command creating new issue order entries:\n%s", PQresultErrorMessage(res));
    1.87 +    err = 1;
    1.88 +    PQclear(res);
    1.89 +  } else {
    1.90 +    if (logging) printf("Created %s new issue order entries.\n", PQcmdTuples(res));
    1.91 +    PQclear(res);
    1.92 +  }
    1.93 +
    1.94    // go through areas:
    1.95    res = PQexec(db, "SELECT \"id\" FROM \"area\"");
    1.96    if (!res) {
    1.97 @@ -490,7 +502,7 @@
    1.98          err = 1;
    1.99          PQclear(res2);
   1.100        } else {
   1.101 -        if (process_area(db, res2, escaped_area_id)) err = 1;
   1.102 +        if (process_area_or_unit(db, res2, escaped_area_id, "area")) err = 1;
   1.103          PQclear(res2);
   1.104        }
   1.105        freemem(escaped_area_id);
   1.106 @@ -498,8 +510,61 @@
   1.107      PQclear(res);
   1.108    }
   1.109  
   1.110 +  // go through units:
   1.111 +  res = PQexec(db, "SELECT \"id\" FROM \"unit\"");
   1.112 +  if (!res) {
   1.113 +    fprintf(stderr, "Error in pqlib while sending SQL command selecting units to process.\n");
   1.114 +    err = 1;
   1.115 +  } else if (PQresultStatus(res) != PGRES_TUPLES_OK) {
   1.116 +    fprintf(stderr, "Error while executing SQL command selecting units to process:\n%s", PQresultErrorMessage(res));
   1.117 +    err = 1;
   1.118 +    PQclear(res);
   1.119 +  } else if (PQnfields(res) < 1) {
   1.120 +    fprintf(stderr, "Too few columns returned by SQL command selecting units to process.\n");
   1.121 +    err = 1;
   1.122 +    PQclear(res);
   1.123 +  } else {
   1.124 +    count = PQntuples(res);
   1.125 +    if (logging) printf("Number of units to process: %i\n", count);
   1.126 +    for (i=0; i<count; i++) {
   1.127 +      char *unit_id, *escaped_unit_id;
   1.128 +      char *cmd;
   1.129 +      PGresult *res2;
   1.130 +      unit_id = PQgetvalue(res, i, 0);
   1.131 +      if (logging) printf("Processing unit #%s:\n", unit_id);
   1.132 +      escaped_unit_id = escapeLiteral(db, unit_id, strlen(unit_id));
   1.133 +      if (!escaped_unit_id) {
   1.134 +        fprintf(stderr, "Could not escape literal in memory.\n");
   1.135 +        abort();
   1.136 +      }
   1.137 +      if (asprintf(&cmd, "SELECT \"member_id\", \"weight\", \"issue_id\" FROM \"issue_supporter_in_admission_state\" WHERE \"unit_id\" = %s ORDER BY \"member_id\"", escaped_unit_id) < 0) {
   1.138 +        fprintf(stderr, "Could not prepare query string in memory.\n");
   1.139 +        abort();
   1.140 +      }
   1.141 +      res2 = PQexec(db, cmd);
   1.142 +      free(cmd);
   1.143 +      if (!res2) {
   1.144 +        fprintf(stderr, "Error in pqlib while sending SQL command selecting issue supporter in admission state.\n");
   1.145 +        err = 1;
   1.146 +      } else if (PQresultStatus(res2) != PGRES_TUPLES_OK) {
   1.147 +        fprintf(stderr, "Error while executing SQL command selecting issue supporter in admission state:\n%s", PQresultErrorMessage(res));
   1.148 +        err = 1;
   1.149 +        PQclear(res2);
   1.150 +      } else if (PQnfields(res2) < 3) {
   1.151 +        fprintf(stderr, "Too few columns returned by SQL command selecting issue supporter in admission state.\n");
   1.152 +        err = 1;
   1.153 +        PQclear(res2);
   1.154 +      } else {
   1.155 +        if (process_area_or_unit(db, res2, escaped_unit_id, "unit")) err = 1;
   1.156 +        PQclear(res2);
   1.157 +      }
   1.158 +      freemem(escaped_unit_id);
   1.159 +    }
   1.160 +    PQclear(res);
   1.161 +  }
   1.162 +
   1.163    // clean-up entries of deleted issues
   1.164 -  res = PQexec(db, "DELETE FROM \"issue_order\" USING \"issue_order\" AS \"issue_order2\" NATURAL LEFT JOIN \"issue\" WHERE \"issue_order\".\"id\" = \"issue_order2\".\"id\" AND \"issue\".\"id\" ISNULL");
   1.165 +  res = PQexec(db, "DELETE FROM \"issue_order_in_admission_state\" USING \"issue_order_in_admission_state\" AS \"self\" NATURAL LEFT JOIN \"issue\" WHERE \"issue_order_in_admission_state\".\"id\" = \"self\".\"id\" AND (\"issue\".\"id\" ISNULL OR \"issue\".\"state\" != 'admission'::\"issue_state\")");
   1.166    if (!res) {
   1.167      fprintf(stderr, "Error in pqlib while sending SQL command deleting ordering data of deleted issues.\n");
   1.168      err = 1;

Impressum / About Us