fix #10 by only using native queries in change processors
This commit is contained in:
parent
21bf05a8ba
commit
36da250ceb
5 changed files with 59 additions and 37 deletions
|
@ -13,10 +13,15 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.faendir.acra.liquibase;
|
package com.faendir.acra.liquibase;
|
||||||
|
|
||||||
import liquibase.changelog.ChangeSet;
|
import liquibase.changelog.ChangeSet;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.persistence.Query;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lukas
|
* @author lukas
|
||||||
|
@ -29,6 +34,16 @@ public abstract class LiquibaseChangePostProcessor {
|
||||||
this.changeId = changeId;
|
this.changeId = changeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
protected void iterate(Supplier<Query> supplier, Consumer<Object> consumer) {
|
||||||
|
int offset = 0;
|
||||||
|
List<?> list;
|
||||||
|
while (!(list = supplier.get().setFirstResult(offset).setMaxResults(64).getResultList()).isEmpty()) {
|
||||||
|
list.forEach(consumer::accept);
|
||||||
|
offset += list.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handle(ChangeSet changeSet) {
|
void handle(ChangeSet changeSet) {
|
||||||
if (changeId.equals(changeSet.getId())) {
|
if (changeId.equals(changeSet.getId())) {
|
||||||
afterChange();
|
afterChange();
|
||||||
|
|
|
@ -13,34 +13,45 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.faendir.acra.liquibase.change;
|
package com.faendir.acra.liquibase.change;
|
||||||
|
|
||||||
import com.faendir.acra.liquibase.LiquibaseChangePostProcessor;
|
import com.faendir.acra.liquibase.LiquibaseChangePostProcessor;
|
||||||
import com.faendir.acra.model.Report;
|
import org.acra.ReportField;
|
||||||
import com.faendir.acra.service.DataService;
|
import org.json.JSONObject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lukas
|
* @author lukas
|
||||||
* @since 01.06.18
|
* @since 01.06.18
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class ReportColumnsChange extends LiquibaseChangePostProcessor {
|
public class ReportColumnsChange extends LiquibaseChangePostProcessor {
|
||||||
|
@NonNull private final EntityManager entityManager;
|
||||||
@NonNull private final DataService dataService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ReportColumnsChange(@NonNull @Lazy DataService dataService) {
|
public ReportColumnsChange(@NonNull @Lazy EntityManager entityManager) {
|
||||||
super("2018-06-01-add-report-columns");
|
super("2018-06-01-add-report-columns");
|
||||||
this.dataService = dataService;
|
this.entityManager = entityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void afterChange() {
|
protected void afterChange() {
|
||||||
dataService.transformAllReports(Report::initFields);
|
iterate(() -> entityManager.createNativeQuery("SELECT content FROM report"), o -> {
|
||||||
|
String content = (String) o;
|
||||||
|
JSONObject json = new JSONObject(content);
|
||||||
|
String id = json.getString(ReportField.REPORT_ID.name());
|
||||||
|
String brand = json.optString(ReportField.BRAND.name());
|
||||||
|
String installationId = json.optString(ReportField.INSTALLATION_ID.name());
|
||||||
|
entityManager.createNativeQuery("UPDATE report SET brand = ?1, installation_id = ?2 WHERE id = ?3")
|
||||||
|
.setParameter(1, brand)
|
||||||
|
.setParameter(2, installationId)
|
||||||
|
.setParameter(3, id)
|
||||||
|
.executeUpdate();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
package com.faendir.acra.liquibase.change;
|
package com.faendir.acra.liquibase.change;
|
||||||
|
|
||||||
import com.faendir.acra.liquibase.LiquibaseChangePostProcessor;
|
import com.faendir.acra.liquibase.LiquibaseChangePostProcessor;
|
||||||
import com.faendir.acra.model.Stacktrace;
|
|
||||||
import com.faendir.acra.service.DataService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
|
@ -31,30 +29,42 @@ import javax.persistence.EntityManager;
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class StacktraceChange extends LiquibaseChangePostProcessor {
|
public class StacktraceChange extends LiquibaseChangePostProcessor {
|
||||||
@NonNull private final DataService dataService;
|
|
||||||
@NonNull private final EntityManager entityManager;
|
@NonNull private final EntityManager entityManager;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public StacktraceChange(@NonNull @Lazy DataService dataService, @NonNull @Lazy EntityManager entityManager) {
|
public StacktraceChange(@NonNull @Lazy EntityManager entityManager) {
|
||||||
super("2018-06-04-add-stacktrace-table");
|
super("2018-06-04-add-stacktrace-table");
|
||||||
this.dataService = dataService;
|
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void afterChange() {
|
protected void afterChange() {
|
||||||
dataService.transformAllReports(report -> {
|
iterate(() -> entityManager.createNativeQuery(
|
||||||
Object[] result = (Object[]) entityManager.createNativeQuery(
|
"SELECT stacktrace, version_code, version_name, bug_id, id FROM report"), o -> {
|
||||||
"SELECT report.stacktrace, report.version_code, report.version_name, report.bug_id FROM report where report.id = ?1")
|
Object[] result = (Object[]) o;
|
||||||
.setParameter(1, report.getId())
|
|
||||||
.getSingleResult();
|
|
||||||
String trace = (String) result[0];
|
String trace = (String) result[0];
|
||||||
int versionCode = (int) result[1];
|
int versionCode = (int) result[1];
|
||||||
String versionName = (String) result[2];
|
String versionName = (String) result[2];
|
||||||
int bugId = (int) result[3];
|
int bugId = (int) result[3];
|
||||||
Stacktrace stacktrace = dataService.findStacktrace(trace)
|
int reportId = (int) result[4];
|
||||||
.orElseGet(() -> new Stacktrace(dataService.findBug(bugId).orElseThrow(IllegalStateException::new), trace, versionCode, versionName));
|
Long stacktraceId = (Long) entityManager.createNativeQuery("SELECT id FROM stacktrace WHERE stacktrace = ?1 AND version_code = ?2")
|
||||||
report.setStacktrace(stacktrace);
|
.setParameter(1, trace)
|
||||||
|
.setParameter(2, versionCode)
|
||||||
|
.setMaxResults(1)
|
||||||
|
.getSingleResult();
|
||||||
|
if(stacktraceId == null) {
|
||||||
|
entityManager.createNativeQuery("INSERT INTO stacktrace (bug_id, stacktrace, version_code, version_name) VALUES(?1, ?2, ?3, ?4)")
|
||||||
|
.setParameter(1, bugId)
|
||||||
|
.setParameter(2, trace)
|
||||||
|
.setParameter(3, versionCode)
|
||||||
|
.setParameter(4, versionName)
|
||||||
|
.executeUpdate();
|
||||||
|
stacktraceId = (Long) entityManager.createNativeQuery("SELECT id FROM stacktrace ORDER BY id DESC").setMaxResults(1).getSingleResult();
|
||||||
|
}
|
||||||
|
entityManager.createNativeQuery("UPDATE report SET stacktrace_id = ?1 WHERE id = ?2")
|
||||||
|
.setParameter(1, stacktraceId)
|
||||||
|
.setParameter(2, reportId)
|
||||||
|
.executeUpdate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,10 +62,6 @@ public class Report {
|
||||||
public Report(@NonNull Stacktrace stacktrace, @NonNull String content) {
|
public Report(@NonNull Stacktrace stacktrace, @NonNull String content) {
|
||||||
this.stacktrace = stacktrace;
|
this.stacktrace = stacktrace;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
initFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void initFields() {
|
|
||||||
this.id = getJsonObject().getString(ReportField.REPORT_ID.name());
|
this.id = getJsonObject().getString(ReportField.REPORT_ID.name());
|
||||||
this.date = Utils.getDateFromString(getJsonObject().optString(ReportField.USER_CRASH_DATE.name()));
|
this.date = Utils.getDateFromString(getJsonObject().optString(ReportField.USER_CRASH_DATE.name()));
|
||||||
this.userEmail = getJsonObject().optString(ReportField.USER_EMAIL.name());
|
this.userEmail = getJsonObject().optString(ReportField.USER_EMAIL.name());
|
||||||
|
|
|
@ -56,6 +56,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.Query;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -338,17 +339,6 @@ public class DataService implements Serializable {
|
||||||
return ((JPAQuery<?>) new JPAQuery<>(entityManager)).from(report).where(where).select(select).distinct().orderBy(order.asc()).fetch();
|
return ((JPAQuery<?>) new JPAQuery<>(entityManager)).from(report).where(where).select(select).distinct().orderBy(order.asc()).fetch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public void transformAllReports(Consumer<Report> consumer) {
|
|
||||||
CloseableIterator<Report> iterator = new JPAQuery<>(entityManager).from(report).select(report).iterate();
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
Report report = iterator.next();
|
|
||||||
consumer.accept(report);
|
|
||||||
store(report);
|
|
||||||
}
|
|
||||||
iterator.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<Stacktrace> getStacktraces(@NonNull Bug bug) {
|
public List<Stacktrace> getStacktraces(@NonNull Bug bug) {
|
||||||
return new JPAQuery<>(entityManager).from(stacktrace1).where(stacktrace1.bug.eq(bug)).select(stacktrace1).fetch();
|
return new JPAQuery<>(entityManager).from(stacktrace1).where(stacktrace1.bug.eq(bug)).select(stacktrace1).fetch();
|
||||||
|
|
Loading…
Reference in a new issue