You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MassUpdate.java 3.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * SonarQube, open source software quality management tool.
  3. * Copyright (C) 2008-2014 SonarSource
  4. * mailto:contact AT sonarsource DOT com
  5. *
  6. * SonarQube is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * SonarQube is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.db.migrations;
  21. import java.sql.Connection;
  22. import java.sql.SQLException;
  23. import java.util.concurrent.atomic.AtomicLong;
  24. import org.sonar.db.Database;
  25. import org.sonar.server.util.ProgressLogger;
  26. public class MassUpdate {
  27. public interface Handler {
  28. /**
  29. * Convert some column values of a given row.
  30. *
  31. * @return true if the row must be updated, else false. If false, then the update parameter must not be touched.
  32. */
  33. boolean handle(Select.Row row, SqlStatement update) throws SQLException;
  34. }
  35. private final Database db;
  36. private final Connection readConnection;
  37. private final Connection writeConnection;
  38. private final AtomicLong counter = new AtomicLong(0L);
  39. private final ProgressLogger progress = ProgressLogger.create(getClass(), counter);
  40. private Select select;
  41. private Upsert update;
  42. MassUpdate(Database db, Connection readConnection, Connection writeConnection) {
  43. this.db = db;
  44. this.readConnection = readConnection;
  45. this.writeConnection = writeConnection;
  46. }
  47. public SqlStatement select(String sql) throws SQLException {
  48. this.select = SelectImpl.create(db, readConnection, sql);
  49. return this.select;
  50. }
  51. public MassUpdate update(String sql) throws SQLException {
  52. this.update = UpsertImpl.create(writeConnection, sql);
  53. return this;
  54. }
  55. public MassUpdate rowPluralName(String s) {
  56. this.progress.setPluralLabel(s);
  57. return this;
  58. }
  59. public void execute(final Handler handler) throws SQLException {
  60. if (select == null || update == null) {
  61. throw new IllegalStateException("SELECT or UPDATE requests are not defined");
  62. }
  63. progress.start();
  64. try {
  65. select.scroll(new Select.RowHandler() {
  66. @Override
  67. public void handle(Select.Row row) throws SQLException {
  68. if (handler.handle(row, update)) {
  69. update.addBatch();
  70. }
  71. counter.getAndIncrement();
  72. }
  73. });
  74. if (((UpsertImpl) update).getBatchCount() > 0L) {
  75. update.execute().commit();
  76. }
  77. update.close();
  78. // log the total number of processed rows
  79. progress.log();
  80. } finally {
  81. progress.stop();
  82. }
  83. }
  84. }