/** * PUBLIC: * Use to specify the names of the mirroring historical tables. * <p> * Explicitly states that <code>sourceTableName</code> is mirrored by history table * <code>historyTableName</code>. * The order in which tables are added with descriptor.addTableName() * should still match the order in which mirroring historical tables are * added with descriptor.addMirroringHistoryTableName(). */ public void addHistoryTableName(String sourceTableName, String historyTableName) { if ((sourceTableName == null) || sourceTableName.equals("")) { addHistoryTableName(historyTableName); } HistoricalDatabaseTable table = new HistoricalDatabaseTable(sourceTableName); table.setHistoricalName(historyTableName); // Note that the equality check is only on sourceTableName, not historyTableName. int index = getHistoricalTables().indexOf(table); if (index == -1) { getHistoricalTables().add(table); } else { getHistoricalTables().set(index, table); } }
/** * INTERNAL: * Add any temporal querying conditions to this object expression. */ public Expression additionalHistoryExpression(Expression context, Expression base) { return additionalHistoryExpression(context, base, null); }
/** * INTERNAL: * Performs a logical insert into the historical schema. Direct * collections and many to many mappings are maintained through the session * events. */ public void mappingLogicalInsert(DataModifyQuery originalQuery, AbstractRecord arguments, AbstractSession session) { DataModifyQuery historyQuery = new DataModifyQuery(); SQLInsertStatement historyStatement = new SQLInsertStatement(); DatabaseTable histTable = getHistoricalTables().get(0); historyStatement.setTable(histTable); AbstractRecord modifyRow = originalQuery.getModifyRow().clone(); AbstractRecord translationRow = arguments.clone(); // Start could be the version field in timestamp locking. if (!modifyRow.containsKey(getStart())) { Object time = getCurrentTime(session); modifyRow.add(getStart(), time); translationRow.add(getStart(), time); } historyQuery.setSQLStatement(historyStatement); historyQuery.setModifyRow(modifyRow); historyStatement.setModifyRow(modifyRow); session.executeQuery(historyQuery, translationRow); }
public void customize(ClassDescriptor descriptor) throws Exception { ManyToManyMapping mapping = (ManyToManyMapping) descriptor.getMappingForAttributeName("segments"); HistoryPolicy policy = new HistoryPolicy(); policy.addStartFieldName("ROW_START"); policy.addEndFieldName("ROW_END"); policy.addHistoryTableName("CLIENT_SEGMENTS", "CLIENT_SEGMENTS_HIST"); mapping.setHistoryPolicy(policy);
/** * PUBLIC: * Performs a sufficiently deep clone. * Use to quickly setup standard policies on multiple descriptors. */ public Object clone() { HistoryPolicy clone = null; try { clone = (HistoryPolicy)super.clone(); } catch (CloneNotSupportedException ignore) { } if (startFields != null) { clone.setStartFields(new ArrayList(startFields.size())); for (DatabaseField field : startFields) { clone.getStartFields().add(field.clone()); } } if (endFields != null) { clone.setEndFields(new ArrayList(endFields.size())); for (DatabaseField field : endFields) { clone.getEndFields().add(field.clone()); } } if (historicalTables != null) { clone.setHistoricalTables(new ArrayList(historicalTables)); } return clone; }
if (getMapping() != null) { setDescriptor(getMapping().getDescriptor()); if (getMapping().isDirectCollectionMapping()) { DatabaseTable refTable = ((DirectCollectionMapping)getMapping()).getReferenceTable(); DatabaseTable histTable = getHistoricalTables().get(0); histTable.setName(refTable.getName()); histTable.setTableQualifier(refTable.getTableQualifier()); getStart().setTable(histTable); getEnd().setTable(histTable); } else if (getMapping().isManyToManyMapping()) { DatabaseTable relationTable = ((ManyToManyMapping)getMapping()).getRelationTable(); DatabaseTable histTable = getHistoricalTables().get(0); histTable.setName(relationTable.getName()); histTable.setTableQualifier(relationTable.getTableQualifier()); getStart().setTable(histTable); getEnd().setTable(histTable); verifyTableQualifiers(session.getPlatform()); return; int offset = getDescriptor().getTables().size() - getHistoricalTables().size(); if (!getHistoricalTables().isEmpty() && getHistoricalTables().get(0).getName().equals("")) { for (int i = 0; i < getHistoricalTables().size(); i++) { DatabaseTable table = getHistoricalTables().get(i); if (table.getName().equals("")) { DatabaseTable mirrored = getDescriptor().getTables().get(i + offset); table.setName(mirrored.getName()); table.setTableQualifier(mirrored.getTableQualifier());
AbstractRecord modifyRow = new DatabaseRecord(); StatementQueryMechanism updateMechanism = new StatementQueryMechanism(writeQuery); Object currentTime = getCurrentTime(writeQuery.getSession()); for (int i = 0; i < getHistoricalTables().size(); i++) { DatabaseTable table = getHistoricalTables().get(i); if (isUpdate && !checkWastedVersioning(originalModifyRow, table)) { continue; whereClause = builder.getField(getEnd(i)).isNull().and(whereClause); updateStatement.setWhereClause(whereClause); modifyRow.add(getEnd(i), currentTime); incrementedTime.setTime(incrementedTime.getTime() + getMinimumTimeIncrement(writeQuery.getSession())); originalModifyRow.add(getStart(i), incrementedTime); } else { originalModifyRow.add(getStart(i), currentTime);
for (Enumeration enumtr = policy.getHistoricalTables().elements(); enumtr.hasMoreElements();) { HistoricalDatabaseTable table = (HistoricalDatabaseTable)enumtr.nextElement(); method.addLine(policyName + ".addHistoryTableName(\"" + sourceName + "\", \"" + historyName + "\");"); for (Enumeration enumtr = policy.getStartFields().elements(); enumtr.hasMoreElements();) { DatabaseField field = (DatabaseField)enumtr.nextElement(); method.addLine(policyName + ".addStartFieldName(\"" + field.getQualifiedName() + "\");"); for (Enumeration enumtr = policy.getEndFields().elements(); enumtr.hasMoreElements();) { DatabaseField field = (DatabaseField)enumtr.nextElement(); method.addLine(policyName + ".addEndFieldName(\"" + field.getQualifiedName() + "\");"); method.addLine(policyName + ".setShouldHandleWrites(" + (policy.shouldHandleWrites() ? "true" : "false") + ");"); if (policy.shouldUseLocalTime()) { method.addLine(policyName + ".useLocalTime();"); } else {
ClassDescriptor descriptor = getDescriptor(); AbstractRecord modifyRow = null; AbstractRecord originalModifyRow = writeQuery.getModifyRow(); modifyRow = originalModifyRow; currentTime = getCurrentTime(writeQuery.getSession()); for (int i = 0; i < getHistoricalTables().size(); i++) { DatabaseTable table = getHistoricalTables().get(i); if (isUpdate && !checkWastedVersioning(originalModifyRow, table)) { continue; modifyRow.add(getStart(i), currentTime);
if (getMapping() != null) { if (tableIndex != null && tableIndex.intValue() > 0) { return null; DatabaseTable historicalTable = getHistoricalTables().get(0); tableExp = (TableExpression)((ObjectExpression)base).existingDerivedTable(historicalTable); start = tableExp.getField(getStart()); end = tableExp.getField(getEnd()); iLast = getHistoricalTables().size() - 1; } else { start = base.getField(getStart(i)); end = base.getField(getEnd(i));
/** * PUBLIC: * Whenever a historical record is logically deleted (updated) or inserted, * the end and start fields respectively will be set to this value. */ public Object getCurrentTime(AbstractSession session) { if (shouldUseLocalTime()) { return new java.sql.Timestamp(System.currentTimeMillis()); } if (shouldUseDatabaseTime()) { AbstractSession readSession = session.getSessionForClass(getDescriptor().getJavaClass()); while (readSession.isUnitOfWork()) { readSession = ((UnitOfWorkImpl)readSession).getParent().getSessionForClass(getDescriptor().getJavaClass()); } return readSession.getDatasourceLogin().getDatasourcePlatform().getTimestampFromServer(session, readSession.getName()); } return null; }
/** * INTERNAL: * Performs a logical delete (update) on the historical schema. Direct * collections and many to many mappings are maintained through the session * events. */ public void mappingLogicalDelete(ModifyQuery originalQuery, AbstractRecord arguments, AbstractSession session) { SQLDeleteStatement originalStatement = (SQLDeleteStatement)originalQuery.getSQLStatement(); DataModifyQuery historyQuery = new DataModifyQuery(); SQLUpdateStatement historyStatement = new SQLUpdateStatement(); DatabaseTable histTable = getHistoricalTables().get(0); historyStatement.setTable(histTable); Expression whereClause = (Expression)originalStatement.getWhereClause().clone(); DatabaseField endField = getEnd(); whereClause = whereClause.getBuilder().getField(endField).isNull().and(whereClause); historyStatement.setWhereClause(whereClause); AbstractRecord modifyRow = new DatabaseRecord(); AbstractRecord translationRow = arguments.clone(); Object time = getCurrentTime(session); modifyRow.add(getEnd(), time); translationRow.add(getEnd(), time); historyStatement.setModifyRow(modifyRow); historyQuery.setSQLStatement(historyStatement); historyQuery.setModifyRow(modifyRow); session.executeQuery(historyQuery, translationRow); } }
/** * PUBLIC: */ public List<String> getHistoryTableNames() { List<String> names = new ArrayList(getHistoricalTables().size()); for (DatabaseTable table : getHistoricalTables()) { names.add(table.getQualifiedName()); } return names; }
builder.asOf(AsOfClause.NO_CLAUSE); Expression temporalExpression = getHistoryPolicy().additionalHistoryExpression(builder); statement.setWhereClause(statement.getWhereClause().and(temporalExpression)); if (builder.hasAsOfClause()) { statement.getTables().set(0, getHistoryPolicy().getHistoricalTables().elementAt(0));
getHistoryPolicy().initialize(session); } else if (hasInheritance()) { setHistoryPolicy((HistoryPolicy)parentDescriptor.getHistoryPolicy().clone());
/** * INTERNAL: * Return a minimal time increment supported by the platform. */ public long getMinimumTimeIncrement(AbstractSession session) { AbstractSession readSession = session.getSessionForClass(getDescriptor().getJavaClass()); while (readSession.isUnitOfWork()) { readSession = ((UnitOfWorkImpl)readSession).getParent().getSessionForClass(getDescriptor().getJavaClass()); } return readSession.getPlatform().minimumTimeIncrement(); }
if (getMapping() != null) { setDescriptor(getMapping().getDescriptor()); if (getMapping().isDirectCollectionMapping()) { DatabaseTable refTable = ((DirectCollectionMapping)getMapping()).getReferenceTable(); DatabaseTable histTable = getHistoricalTables().get(0); histTable.setName(refTable.getName()); histTable.setTableQualifier(refTable.getTableQualifier()); getStart().setTable(histTable); getEnd().setTable(histTable); } else if (getMapping().isManyToManyMapping()) { DatabaseTable relationTable = ((ManyToManyMapping)getMapping()).getRelationTable(); DatabaseTable histTable = getHistoricalTables().get(0); histTable.setName(relationTable.getName()); histTable.setTableQualifier(relationTable.getTableQualifier()); getStart().setTable(histTable); getEnd().setTable(histTable); verifyTableQualifiers(session.getPlatform()); return; int offset = getDescriptor().getTables().size() - getHistoricalTables().size(); if (!getHistoricalTables().isEmpty() && getHistoricalTables().get(0).getName().equals("")) { for (int i = 0; i < getHistoricalTables().size(); i++) { DatabaseTable table = getHistoricalTables().get(i); if (table.getName().equals("")) { DatabaseTable mirrored = getDescriptor().getTables().get(i + offset); table.setName(mirrored.getName()); table.setTableQualifier(mirrored.getTableQualifier());
AbstractRecord modifyRow = new DatabaseRecord(); StatementQueryMechanism updateMechanism = new StatementQueryMechanism(writeQuery); Object currentTime = getCurrentTime(writeQuery.getSession()); for (int i = 0; i < getHistoricalTables().size(); i++) { DatabaseTable table = getHistoricalTables().get(i); if (isUpdate && !checkWastedVersioning(originalModifyRow, table)) { continue; whereClause = builder.getField(getEnd(i)).isNull().and(whereClause); updateStatement.setWhereClause(whereClause); modifyRow.add(getEnd(i), currentTime); incrementedTime.setTime(incrementedTime.getTime() + getMinimumTimeIncrement(writeQuery.getSession())); originalModifyRow.add(getStart(i), incrementedTime); } else { originalModifyRow.add(getStart(i), currentTime);
protected void addHistoryPolicyLines(NonreflectiveMethodDefinition method, HistoryPolicy policy, String policyName) { method.addLine(""); method.addLine("// History Policy"); method.addLine("HistoryPolicy " + policyName + " = new HistoryPolicy();"); for (DatabaseTable table : policy.getHistoricalTables()) { String sourceName = null; if (table.getTableQualifier().equals("")) { sourceName = table.getName(); } else { sourceName = table.getTableQualifier() + "." + table.getName(); } String historyName = table.getQualifiedName(); method.addLine(policyName + ".addHistoryTableName(\"" + sourceName + "\", \"" + historyName + "\");"); } for (DatabaseField field : policy.getStartFields()) { method.addLine(policyName + ".addStartFieldName(\"" + field.getQualifiedName() + "\");"); // Field classifications don't seem to be supported in workbench integration. //method.addLine(policyName + ".setStartFieldType(\"" + field.getQualifiedName() + "\", " + field.getType().getName() + ".class);"); } for (DatabaseField field : policy.getEndFields()) { method.addLine(policyName + ".addEndFieldName(\"" + field.getQualifiedName() + "\");"); //method.addLine(policyName + ".setEndFieldType(\"" + field.getQualifiedName() + "\", " + field.getType().getName() + ".class);"); } method.addLine(policyName + ".setShouldHandleWrites(" + (policy.shouldHandleWrites() ? "true" : "false") + ");"); if (policy.shouldUseLocalTime()) { method.addLine(policyName + ".useLocalTime();"); } else { method.addLine(policyName + ".useDatabaseTime();"); } }