-
Notifications
You must be signed in to change notification settings - Fork 372
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CLDR-15850 Collect type of vote: direct, auto/manual import, bulk upload #2777
Changes from all commits
8b15f98
6127f22
3dd740c
7bd807a
93db439
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,7 +133,11 @@ public int getSize(CLDRLocale locale, String xpath) { | |
|
||
} | ||
|
||
/** | ||
* Names of some columns in DBUtils.Table.VOTE_VALUE | ||
*/ | ||
private static final String VOTE_OVERRIDE = "vote_override"; | ||
private static final String VOTE_TYPE = "vote_type"; | ||
|
||
private class DataBackedSource extends DelegateXMLSource { | ||
PerLocaleData ballotBox; | ||
|
@@ -991,13 +995,23 @@ public void revoteFor(User user, String distinguishingXpath) throws BallotBox.In | |
voteForValue(user, distinguishingXpath, oldValue); | ||
} | ||
|
||
@Override | ||
public void voteForValue(User user, String distinguishingXpath, String value, Integer withVote) throws InvalidXPathException, VoteNotAcceptedException { | ||
voteForValueWithType(user, distinguishingXpath, value, withVote, VoteType.DIRECT); | ||
} | ||
|
||
@Override | ||
public void voteForValue(User user, String distinguishingXpath, String value) throws InvalidXPathException, VoteNotAcceptedException { | ||
voteForValue(user, distinguishingXpath, value, null); | ||
voteForValueWithType(user, distinguishingXpath, value, null, VoteType.DIRECT); | ||
} | ||
|
||
@Override | ||
public synchronized void voteForValue(User user, String distinguishingXpath, String value, Integer withVote) throws BallotBox.InvalidXPathException, | ||
public void voteForValueWithType(User user, String distinguishingXpath, String value, VoteType voteType) throws VoteNotAcceptedException, InvalidXPathException { | ||
voteForValueWithType(user, distinguishingXpath, value, null, voteType); | ||
} | ||
|
||
@Override | ||
public synchronized void voteForValueWithType(User user, String distinguishingXpath, String value, Integer withVote, VoteType voteType) throws BallotBox.InvalidXPathException, | ||
BallotBox.VoteNotAcceptedException { | ||
makeSureInPathsForFile(distinguishingXpath, user, value); | ||
value = processValue(distinguishingXpath, value); | ||
|
@@ -1011,11 +1025,7 @@ public synchronized void voteForValue(User user, String distinguishingXpath, Str | |
} | ||
|
||
int xpathId = sm.xpt.getByXpath(distinguishingXpath); | ||
boolean voteIsAutoImported = false; | ||
if (VOTE_IS_AUTO_IMPORTED.equals(withVote)) { | ||
withVote = null; | ||
voteIsAutoImported = true; | ||
} else if (withVote != null) { | ||
if (withVote != null) { | ||
Level level = user.getLevel(); | ||
if (withVote == level.getVotes(user.getOrganization())) { | ||
withVote = null; // not an override | ||
|
@@ -1042,7 +1052,7 @@ public synchronized void voteForValue(User user, String distinguishingXpath, Str | |
String oldVal = xmlsource.getValueAtDPath(distinguishingXpath); | ||
|
||
if (!readonly) { | ||
saveVoteToDb(user, distinguishingXpath, value, withVote, xpathId, voteIsAutoImported); | ||
saveVoteToDb(user, distinguishingXpath, value, withVote, xpathId, voteType); | ||
} else { | ||
readonly(); | ||
} | ||
|
@@ -1132,16 +1142,14 @@ private DisplayAndInputProcessor getProcessor() { | |
* @param xpathId | ||
*/ | ||
private void saveVoteToDb(final User user, final String distinguishingXpath, final String value, | ||
final Integer withVote, final int xpathId, boolean voteIsAutoImported) { | ||
final Integer withVote, final int xpathId, VoteType voteType) { | ||
boolean didClearFlag = false; | ||
makeSource(false); | ||
ElapsedTimer et = !SurveyLog.DEBUG ? null : new ElapsedTimer("{0} Recording PLD for " + locale + " " | ||
+ distinguishingXpath + " : " + user + " voting for '" + value); | ||
Connection conn = null; | ||
PreparedStatement saveOld = null; // save off old value | ||
PreparedStatement ps = null; // all for mysql, or 1st step for | ||
// derby | ||
PreparedStatement ps2 = null; // 2nd step for derby | ||
PreparedStatement ps = null; | ||
final boolean wasFlagged = getFlag(locale, xpathId); // do this outside of the txn.. | ||
int submitter = user.id; | ||
try { | ||
|
@@ -1152,13 +1160,8 @@ private void saveVoteToDb(final User user, final String distinguishingXpath, fin | |
// #1 - save the "VOTE_VALUE_ALT" ( possible proposal) value. | ||
if (DBUtils.db_Mysql) { | ||
add0 = "IGNORE"; | ||
// add1="ON DUPLICATE KEY IGNORE"; | ||
} else { | ||
add2 = "and not exists (select * from " + DBUtils.Table.VOTE_VALUE_ALT | ||
+ " where " + DBUtils.Table.VOTE_VALUE_ALT + ".locale=" | ||
+ DBUtils.Table.VOTE_VALUE + ".locale and " | ||
+ DBUtils.Table.VOTE_VALUE_ALT + ".xpath=" + DBUtils.Table.VOTE_VALUE + ".xpath and " | ||
+ DBUtils.Table.VOTE_VALUE_ALT + ".value=" + DBUtils.Table.VOTE_VALUE + ".value )"; | ||
throw new RuntimeException("Unexpected db type, expected " + DBUtils.db_Mysql); | ||
} | ||
String sql = "insert " + add0 + " into " + DBUtils.Table.VOTE_VALUE_ALT + " " + add1 | ||
+ " select " + DBUtils.Table.VOTE_VALUE + ".locale," | ||
|
@@ -1169,36 +1172,17 @@ private void saveVoteToDb(final User user, final String distinguishingXpath, fin | |
saveOld.executeUpdate(); | ||
|
||
// #2 - save the actual vote. | ||
if (DBUtils.db_Mysql) { // use 'on duplicate key' syntax | ||
ps = DBUtils.prepareForwardReadOnly(conn, "INSERT INTO " + DBUtils.Table.VOTE_VALUE | ||
+ " (locale,xpath,submitter,value,last_mod," + VOTE_OVERRIDE + ") values (?,?,?,?,CURRENT_TIMESTAMP,?) " | ||
+ "ON DUPLICATE KEY UPDATE locale=?,xpath=?,submitter=?,value=?,last_mod=CURRENT_TIMESTAMP," + VOTE_OVERRIDE + "=?"); | ||
int colNum = 6; | ||
ps = DBUtils.prepareForwardReadOnly(conn, "INSERT INTO " + DBUtils.Table.VOTE_VALUE | ||
+ " (locale,xpath,submitter,value,last_mod," + VOTE_OVERRIDE + "," + VOTE_TYPE + ") values (?,?,?,?,CURRENT_TIMESTAMP,?,?) " | ||
+ "ON DUPLICATE KEY UPDATE locale=?,xpath=?,submitter=?,value=?,last_mod=CURRENT_TIMESTAMP," + VOTE_OVERRIDE + "=?," + VOTE_TYPE + "=?"); | ||
int colNum = 1; | ||
for (int repeat = 1; repeat <= 2; repeat++) { | ||
ps.setString(colNum++, locale.getBaseName()); | ||
ps.setInt(colNum++, xpathId); | ||
ps.setInt(colNum++, submitter); | ||
DBUtils.setStringUTF8(ps, colNum++, value); | ||
DBUtils.setInteger(ps, colNum++, withVote); | ||
} else { // derby | ||
ps2 = DBUtils.prepareForwardReadOnly(conn, "DELETE FROM " + DBUtils.Table.VOTE_VALUE | ||
+ " where locale=? and xpath=? and submitter=? "); | ||
ps = DBUtils.prepareForwardReadOnly(conn, "INSERT INTO " + DBUtils.Table.VOTE_VALUE | ||
+ " (locale,xpath,submitter,value,last_mod," + VOTE_OVERRIDE + ") VALUES (?,?,?,?,CURRENT_TIMESTAMP,?) "); | ||
int colNum = 1; | ||
ps2.setString(colNum++, locale.getBaseName()); | ||
ps2.setInt(colNum++, xpathId); | ||
ps2.setInt(colNum++, submitter); | ||
// NB: no "VOTE_OVERRIDE" column on delete. | ||
} | ||
|
||
int colNum = 1; | ||
ps.setString(colNum++, locale.getBaseName()); | ||
ps.setInt(colNum++, xpathId); | ||
ps.setInt(colNum++, submitter); | ||
DBUtils.setStringUTF8(ps, colNum++, value); | ||
DBUtils.setInteger(ps, colNum++, withVote); | ||
if (ps2 != null) { | ||
ps2.executeUpdate(); | ||
DBUtils.setInteger(ps, colNum++, voteType.id()); | ||
} | ||
ps.executeUpdate(); | ||
|
||
|
@@ -1209,14 +1193,16 @@ private void saveVoteToDb(final User user, final String distinguishingXpath, fin | |
conn.commit(); | ||
} catch (SQLException e) { | ||
SurveyLog.logException(logger, e, "Exception in saveVoteToDb"); | ||
SurveyMain.busted("Could not vote for value in locale locale " + locale, e); | ||
SurveyMain.busted("Could not vote for value in locale " + locale, e); | ||
throw new InternalError("Could not load locale " + locale + " : " + DBUtils.unchainSqlException(e)); | ||
} finally { | ||
DBUtils.close(saveOld, ps, ps2, conn); | ||
DBUtils.close(saveOld, ps, conn); | ||
} | ||
SurveyLog.debug(et); | ||
|
||
if (sm.fora != null && !voteIsAutoImported) { | ||
// Voting can trigger adding a forum post (agree/decline) and/or closing a forum thread. | ||
// AUTO_IMPORT and MANUAL_IMPORT votes are excluded; DIRECT and BULK_UPLOAD are not excluded. | ||
if (sm.fora != null && (voteType != VoteType.AUTO_IMPORT && voteType != VoteType.MANUAL_IMPORT)) { | ||
sm.fora.doForumAfterVote(locale, user, distinguishingXpath, xpathId, value, didClearFlag); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The exclusion of MANUAL_IMPORT is new -- I'm not sure whether such forum posts have been made, but they would be very strange given that such votes are done in the name of an anonymous "user", and so the forum posts would also be from anonymous users (whose votes have zero weight) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked the db -- there has been exactly one forum post by an anonymous user:
It's an "Agree" post (type 3). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know how an anonymous user would post. Almost sounds like an error? |
||
} | ||
} | ||
|
@@ -1748,24 +1734,16 @@ private synchronized void setupDB() { | |
Statement s = null; | ||
try (Connection conn = DBUtils.getInstance().getDBConnection()) { | ||
if (!DBUtils.hasTable(DBUtils.Table.VOTE_VALUE.toString())) { | ||
/* | ||
* CREATE TABLE cldr_votevalue ( locale VARCHAR(20), xpath INT | ||
* NOT NULL, submitter INT NOT NULL, value BLOB ); | ||
* | ||
* CREATE UNIQUE INDEX cldr_votevalue_unique ON cldr_votevalue | ||
* (locale,xpath,submitter); | ||
*/ | ||
s = conn.createStatement(); | ||
|
||
sql = "create table " + DBUtils.Table.VOTE_VALUE + "( " | ||
sql = "CREATE TABLE " + DBUtils.Table.VOTE_VALUE + "( " | ||
+ "locale VARCHAR(20), " | ||
+ "xpath INT NOT NULL, " | ||
+ "submitter INT NOT NULL, " + "value " + DBUtils.DB_SQL_UNICODE + ", " | ||
+ DBUtils.DB_SQL_LAST_MOD + ", " | ||
+ VOTE_OVERRIDE + " INT DEFAULT NULL, " | ||
+ " PRIMARY KEY (locale,submitter,xpath) " + | ||
|
||
" )"; | ||
+ VOTE_TYPE + " TINYINT NOT NULL, " | ||
+ "PRIMARY KEY (locale,submitter,xpath) " + | ||
")"; | ||
// logger.info(sql); | ||
s.execute(sql); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.unicode.cldr.util; | ||
|
||
public enum VoteType { | ||
UNKNOWN(0), DIRECT(1), AUTO_IMPORT (2) , MANUAL_IMPORT(3), BULK_UPLOAD(4); | ||
|
||
private final int integerId; | ||
|
||
VoteType(int id) { | ||
this.integerId = id; | ||
} | ||
|
||
/** | ||
* Get an integer version of the type, for compact database storage as TINYINT | ||
* | ||
* @return the vote type integer id | ||
*/ | ||
public int id() { | ||
return integerId; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed. As of #2778,
DBUtils.db_Mysql
ispublic static final boolean db_Mysql = true;
. I'm just going to be deleting this line soon.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good!