org.sonar.db.version.v51.CopyScmAccountsFromAuthorsToUsers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sonar-db Show documentation
Show all versions of sonar-db Show documentation
Create and request SonarQube schema
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.db.version.v51;
import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.CheckForNull;
import org.sonar.api.utils.System2;
import org.sonar.core.util.ProgressLogger;
import org.sonar.db.Database;
import org.sonar.db.version.BaseDataChange;
import org.sonar.db.version.Select;
import org.sonar.db.version.Upsert;
import org.sonar.db.version.UpsertImpl;
import static com.google.common.collect.Lists.newArrayList;
public class CopyScmAccountsFromAuthorsToUsers extends BaseDataChange {
private static final char SCM_ACCOUNTS_SEPARATOR = '\n';
private final System2 system;
private final AtomicLong counter = new AtomicLong(0L);
public CopyScmAccountsFromAuthorsToUsers(Database db, System2 system) {
super(db);
this.system = system;
}
@Override
public void execute(final Context context) throws SQLException {
ProgressLogger progress = ProgressLogger.create(getClass(), counter);
progress.start();
final Long now = system.now();
try {
final Multimap authorsByPersonId = ArrayListMultimap.create();
context.prepareSelect("SELECT a.person_id, a.login FROM authors a," +
" (SELECT person_id, COUNT(*) AS nb FROM authors GROUP BY person_id HAVING COUNT(*) > 1) group_by_person" +
" WHERE a.person_id = group_by_person.person_id "
).scroll(new AuthorsByPersonIdHandler(authorsByPersonId));
Upsert update = context.prepareUpsert("UPDATE users SET scm_accounts = ?, updated_at = ? WHERE id = ?");
for (Long personId : authorsByPersonId.keySet()) {
List authors = newArrayList(authorsByPersonId.get(personId));
List users = selectUsersFromLoginOrEmail(context, authors);
if (users.size() == 1) {
User user = users.get(0);
if (authors.contains(user.login)) {
authors.remove(user.login);
}
if (authors.contains(user.email)) {
authors.remove(user.email);
}
if (!authors.isEmpty()) {
update
.setString(1, encodeScmAccounts(authors))
.setLong(2, now)
.setLong(3, user.id)
.addBatch();
counter.getAndIncrement();
}
}
}
if (((UpsertImpl) update).getBatchCount() > 0L) {
update.execute().commit();
}
update.close();
progress.log();
} finally {
progress.stop();
}
}
private List selectUsersFromLoginOrEmail(Context context, Collection authors) throws SQLException {
final List users = newArrayList();
StringBuilder sql = new StringBuilder("SELECT u.id, u.login, u.email, u.scm_accounts FROM users u WHERE u.active=? AND (");
for (int i = 0; i < authors.size(); i++) {
if (i < authors.size() - 1) {
sql.append("u.login=? OR u.email=? OR ");
} else {
sql.append("u.login=? OR u.email=?)");
}
}
Select select = context.prepareSelect(sql.toString());
select.setBoolean(1, true);
int currentIndex = 1;
for (String author : authors) {
currentIndex++;
select.setString(currentIndex, author);
currentIndex++;
select.setString(currentIndex, author);
}
select.scroll(new UsersHandler(users));
return users;
}
@CheckForNull
private static String encodeScmAccounts(List scmAccounts) {
if (scmAccounts.isEmpty()) {
return null;
}
return SCM_ACCOUNTS_SEPARATOR + Joiner.on(SCM_ACCOUNTS_SEPARATOR).join(scmAccounts) + SCM_ACCOUNTS_SEPARATOR;
}
private static class User {
Long id;
String login;
String email;
String scmAccounts;
User(Long id, String login, String email, String scmAccounts) {
this.id = id;
this.login = login;
this.email = email;
this.scmAccounts = scmAccounts;
}
}
private static class AuthorsByPersonIdHandler implements Select.RowHandler {
private final Multimap authorsByPersonId;
private AuthorsByPersonIdHandler(Multimap authorsByPersonId) {
this.authorsByPersonId = authorsByPersonId;
}
@Override
public void handle(Select.Row row) throws SQLException {
authorsByPersonId.put(row.getNullableLong(1), row.getNullableString(2));
}
}
private static class UsersHandler implements Select.RowHandler {
private final List users;
private UsersHandler(List users) {
this.users = users;
}
@Override
public void handle(Select.Row row) throws SQLException {
users.add(new User(row.getNullableLong(1), row.getNullableString(2), row.getNullableString(3), row.getNullableString(4)));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy