use of org.qi4j.spi.entity.EntityStatus in project qi4j-sdk by Qi4j.
the class AbstractSQLIndexing method indexEntities.
@Override
public void indexEntities(Iterable<EntityState> changedStates) throws SQLException {
final String schemaName = this._state.schemaName().get();
final SQLVendor vendor = this.descriptor.metaInfo(SQLVendor.class);
Connection connectionTest = AbstractSQLStartup.CONNECTION_FOR_REINDEXING.get();
boolean connectionFromStartupWasNull = connectionTest == null;
boolean wasAutoCommit = false;
boolean wasReadOnly = false;
if (connectionFromStartupWasNull) {
connectionTest = this._dataSource.getConnection();
} else {
wasAutoCommit = connectionTest.getAutoCommit();
wasReadOnly = connectionTest.isReadOnly();
}
final Connection connection = connectionTest;
PreparedStatement updateEntityTablePS = null;
PreparedStatement removeEntityPS = null;
PreparedStatement insertToPropertyQNamesPS = null;
PreparedStatement clearEntityDataPS = null;
Lazy<PreparedStatement, SQLException> queryEntityPKPS = new Lazy<>(new LazyInit<PreparedStatement, SQLException>() {
@Override
public PreparedStatement create() throws SQLException {
return connection.prepareStatement(vendor.toString(createQueryEntityPkByIdentityStatement(schemaName, vendor)));
}
});
Lazy<PreparedStatement, SQLException> insertToEntityTableAutoGenerated = new Lazy<>(new LazyInit<PreparedStatement, SQLException>() {
@Override
public PreparedStatement create() throws SQLException {
return connection.prepareStatement(createInsertStatementWithAutoGeneratedIDForEntitiesTable(schemaName, ENTITY_TABLE_NAME, vendor).toString());
}
});
Lazy<PreparedStatement, SQLException> insertToEntityTypeTablePS = new Lazy<>(new LazyInit<PreparedStatement, SQLException>() {
@Override
public PreparedStatement create() throws SQLException {
return connection.prepareStatement(createInsertEntityTypeStatement(schemaName, vendor).toString());
}
});
Map<QualifiedName, PreparedStatement> qNameInsertPSs = new HashMap<>();
try {
connection.setAutoCommit(false);
connection.setReadOnly(false);
// TODO cache all queries.
updateEntityTablePS = connection.prepareStatement(this.createUpdateEntityTableStatement(schemaName, vendor).toString());
removeEntityPS = connection.prepareStatement(this.createDeleteFromEntityTableStatement(schemaName, vendor).toString());
insertToPropertyQNamesPS = connection.prepareStatement(vendor.toString(this.createInsertStatement(schemaName, DBNames.ALL_QNAMES_TABLE_NAME, AMOUNT_OF_COLUMNS_IN_ALL_QNAMES_TABLE, vendor)));
clearEntityDataPS = connection.prepareStatement(this.createClearEntityDataStatement(schemaName, vendor).toString());
Map<Long, EntityState> statesByPK = new HashMap<>();
Map<Long, Integer> qNamePKs = new HashMap<>();
Iterable<EntityState> relatedStates = Iterables.filter(new Specification<EntityState>() {
@Override
public boolean satisfiedBy(EntityState item) {
return item.entityDescriptor().queryable();
}
}, Iterables.map(SQLCompatEntityStateWrapper.WRAP, changedStates));
for (EntityState eState : relatedStates) {
EntityStatus status = eState.status();
Long pk = null;
boolean needToInsert = status.equals(EntityStatus.NEW);
if (!needToInsert) {
if (status.equals(EntityStatus.UPDATED)) {
pk = this.findEntityPK(eState, queryEntityPKPS);
if (pk == null) {
// Happens when reindexing
needToInsert = true;
} else {
// TODO if multiple applications with different application model use
// indexing, need to sync type-table.
this.updateEntityInfoAndProperties(connection, qNameInsertPSs, insertToPropertyQNamesPS, clearEntityDataPS, updateEntityTablePS, eState, pk, qNamePKs);
}
} else if (status.equals(EntityStatus.REMOVED)) {
this.removeEntity(eState, removeEntityPS);
} else {
// TODO possibly handle LOADED state somehow
// throw new
// UnsupportedOperationException("Did not understand what to do with state [id = "
// +
// eState.identity().identity() + ", status = " + status + "].");
}
}
if (needToInsert) {
pk = this.getPKFromAutoGeneratedIDInsert(eState, insertToEntityTableAutoGenerated.getValue(), vendor, connection);
this.insertPropertyType(connection, insertToEntityTypeTablePS.getValue(), eState, pk);
this.insertProperties(connection, qNameInsertPSs, insertToPropertyQNamesPS, eState, pk, qNamePKs);
}
if (pk != null) {
statesByPK.put(pk, eState);
}
}
removeEntityPS.executeBatch();
updateEntityTablePS.executeBatch();
clearEntityDataPS.executeBatch();
if (insertToEntityTypeTablePS.hasValue()) {
insertToEntityTypeTablePS.getValue().executeBatch();
}
for (Map.Entry<Long, EntityState> entry : statesByPK.entrySet()) {
EntityState eState = entry.getValue();
Long pk = entry.getKey();
this.insertAssoAndManyAssoQNames(qNameInsertPSs, insertToPropertyQNamesPS, eState, qNamePKs.get(pk), pk);
}
insertToPropertyQNamesPS.executeBatch();
for (PreparedStatement ps : qNameInsertPSs.values()) {
ps.executeBatch();
}
connection.commit();
} catch (SQLException sqle) {
SQLUtil.rollbackQuietly(connection);
throw sqle;
} finally {
try {
if (queryEntityPKPS.hasValue()) {
SQLUtil.closeQuietly(queryEntityPKPS.getValue());
}
if (insertToEntityTableAutoGenerated.hasValue()) {
SQLUtil.closeQuietly(insertToEntityTableAutoGenerated.getValue());
}
SQLUtil.closeQuietly(updateEntityTablePS);
SQLUtil.closeQuietly(removeEntityPS);
SQLUtil.closeQuietly(insertToPropertyQNamesPS);
SQLUtil.closeQuietly(clearEntityDataPS);
for (PreparedStatement ps : qNameInsertPSs.values()) {
SQLUtil.closeQuietly(ps);
}
} finally {
if (connectionFromStartupWasNull) {
SQLUtil.closeQuietly(connection);
} else {
connection.setReadOnly(wasReadOnly);
connection.setAutoCommit(wasAutoCommit);
}
}
}
}
Aggregations