Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn F. Cook2011-08-02 16:05:40 -0400
committerRyan D. Brooks2011-08-02 16:05:40 -0400
commitdad30d551e147defe4d124ec94b7c6aa704b08cf (patch)
treedf00bdb845c0acdda98346d6650f1b25c749ad25 /plugins/org.eclipse.osee.framework.database
parenta75fa5b6a515a19ae050b72a1d53ce1abc8b40c8 (diff)
downloadorg.eclipse.osee-dad30d551e147defe4d124ec94b7c6aa704b08cf.tar.gz
org.eclipse.osee-dad30d551e147defe4d124ec94b7c6aa704b08cf.tar.xz
org.eclipse.osee-dad30d551e147defe4d124ec94b7c6aa704b08cf.zip
refinement[bgz_350331]: Migrate PurgeTransactionBlam to server side command line
Diffstat (limited to 'plugins/org.eclipse.osee.framework.database')
-rw-r--r--plugins/org.eclipse.osee.framework.database/META-INF/MANIFEST.MF4
-rw-r--r--plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/core/DatabaseTransactions.java1
-rw-r--r--plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/internal/Activator.java9
-rw-r--r--plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/operation/PurgeTransactionOperation.java320
4 files changed, 332 insertions, 2 deletions
diff --git a/plugins/org.eclipse.osee.framework.database/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.framework.database/META-INF/MANIFEST.MF
index 172e4e9521..ba24cb272b 100644
--- a/plugins/org.eclipse.osee.framework.database/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.osee.framework.database/META-INF/MANIFEST.MF
@@ -9,6 +9,7 @@ Export-Package: org.eclipse.osee.framework.database,
org.eclipse.osee.framework.database.operation
Bundle-ActivationPolicy: lazy
Eclipse-ExtensibleAPI: true
+DynamicImport-Package: *
Bundle-Vendor: Eclipse Open System Engineering Environment
Import-Package: org.eclipse.core.runtime,
org.eclipse.core.runtime.jobs,
@@ -16,6 +17,8 @@ Import-Package: org.eclipse.core.runtime,
org.eclipse.osee.framework.core.data,
org.eclipse.osee.framework.core.enums,
org.eclipse.osee.framework.core.exception,
+ org.eclipse.osee.framework.core.model,
+ org.eclipse.osee.framework.core.model.cache,
org.eclipse.osee.framework.core.operation,
org.eclipse.osee.framework.core.services,
org.eclipse.osee.framework.core.util,
@@ -30,4 +33,3 @@ Import-Package: org.eclipse.core.runtime,
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Service-Component: OSGI-INF/uri.connection.contributor.xml
Require-Bundle: org.eclipse.equinox.ds
-DynamicImport-Package: *
diff --git a/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/core/DatabaseTransactions.java b/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/core/DatabaseTransactions.java
index c45d67b352..797611b985 100644
--- a/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/core/DatabaseTransactions.java
+++ b/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/core/DatabaseTransactions.java
@@ -69,5 +69,4 @@ public final class DatabaseTransactions {
}
}
}
-
}
diff --git a/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/internal/Activator.java b/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/internal/Activator.java
index 0029b142d7..5f9f7fce14 100644
--- a/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/internal/Activator.java
+++ b/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/internal/Activator.java
@@ -11,6 +11,7 @@
package org.eclipse.osee.framework.database.internal;
import org.eclipse.osee.framework.core.exception.OseeDataStoreException;
+import org.eclipse.osee.framework.core.services.IOseeCachingService;
import org.eclipse.osee.framework.core.util.ServiceDependencyTracker;
import org.eclipse.osee.framework.database.IOseeDatabaseService;
import org.eclipse.osee.framework.database.IOseeDatabaseServiceProvider;
@@ -29,6 +30,7 @@ public class Activator implements BundleActivator, IOseeDatabaseServiceProvider
private ServiceDependencyTracker databaseServiceTracker;
private ServiceTracker dbTracker;
+ private ServiceTracker cacheTracker;
private DatabaseInfoProvider databaseInfoProvider;
@Override
@@ -42,6 +44,9 @@ public class Activator implements BundleActivator, IOseeDatabaseServiceProvider
dbTracker = new ServiceTracker(bundleContext, IOseeDatabaseService.class.getName(), null);
dbTracker.open(true);
+
+ cacheTracker = new ServiceTracker(bundleContext, IOseeCachingService.class.getName(), null);
+ cacheTracker.open(true);
}
public DatabaseInfoProvider getDatabaseInfoProvider() {
@@ -61,6 +66,7 @@ public class Activator implements BundleActivator, IOseeDatabaseServiceProvider
public void stop(BundleContext context) throws Exception {
databaseServiceTracker.close();
dbTracker.close();
+ cacheTracker.close();
databaseInfoProvider = null;
instance = null;
}
@@ -69,4 +75,7 @@ public class Activator implements BundleActivator, IOseeDatabaseServiceProvider
return instance;
}
+ public static IOseeCachingService getOseeCachingService() {
+ return (IOseeCachingService) getInstance().cacheTracker.getService();
+ }
}
diff --git a/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/operation/PurgeTransactionOperation.java b/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/operation/PurgeTransactionOperation.java
new file mode 100644
index 0000000000..854fb57907
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.database/src/org/eclipse/osee/framework/database/operation/PurgeTransactionOperation.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2007 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.osee.framework.database.operation;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.logging.Level;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.osee.framework.core.enums.ModificationType;
+import org.eclipse.osee.framework.core.enums.TxChange;
+import org.eclipse.osee.framework.core.exception.OseeArgumentException;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.TransactionDoesNotExist;
+import org.eclipse.osee.framework.core.model.TransactionRecord;
+import org.eclipse.osee.framework.core.model.cache.TransactionCache;
+import org.eclipse.osee.framework.core.operation.OperationLogger;
+import org.eclipse.osee.framework.core.util.Conditions;
+import org.eclipse.osee.framework.database.IOseeDatabaseService;
+import org.eclipse.osee.framework.database.core.AbstractDbTxOperation;
+import org.eclipse.osee.framework.database.core.ConnectionHandler;
+import org.eclipse.osee.framework.database.core.IOseeStatement;
+import org.eclipse.osee.framework.database.core.IdJoinQuery;
+import org.eclipse.osee.framework.database.core.JoinUtility;
+import org.eclipse.osee.framework.database.core.OseeConnection;
+import org.eclipse.osee.framework.database.core.TransactionJoinQuery;
+import org.eclipse.osee.framework.database.internal.Activator;
+import org.eclipse.osee.framework.logging.OseeLog;
+
+/**
+ * @author Ryan D. Brooks
+ */
+public class PurgeTransactionOperation extends AbstractDbTxOperation {
+
+ private static final String UPDATE_TXS_DETAILS_COMMENT =
+ "UPDATE osee_tx_details SET osee_comment = replace(osee_comment, ?, ?) WHERE osee_comment like ?";
+
+ private static final String SELECT_GAMMAS_FROM_TRANSACTION =
+ "SELECT DISTINCT txs1.gamma_id FROM osee_txs txs1, osee_join_transaction txj1 WHERE txs1.transaction_id = txj1.transaction_id AND txj1.query_id = ? AND NOT EXISTS (SELECT 'x' FROM osee_txs txs2 WHERE txs1.gamma_id = txs2.gamma_id AND txs1.transaction_id <> txs2.transaction_id)";
+
+ private final static String DELETE_TXS = "delete from osee_txs where transaction_id = ?";
+ private static final String DELETE_TX_DETAILS = "delete from osee_tx_details where transaction_id = ?";
+
+ private final static String DELETE_ARTIFACT_VERSIONS = "delete from osee_artifact items where items.gamma_id = ?";
+ private final static String DELETE_ATTRIBUTES = "delete from osee_attribute items where items.gamma_id = ?";
+ private final static String DELETE_RELATIONS = "delete from osee_relation_link items where items.gamma_id = ?";
+
+ private final static String TRANSACATION_GAMMA_IN_USE =
+ "SELECT txs2.transaction_id FROM osee_txs txs1, osee_txs txs2, osee_join_transaction jn where txs1.transaction_id = jn.transaction_id AND txs1.gamma_id = txs2.gamma_id and txs2.transaction_id != txs1.transaction_id AND jn.query_id = ?";
+
+ private final static String SELECT_AFFECTED_ITEMS =
+ "SELECT %s as item_id, txs.branch_id from osee_join_transaction ojt, osee_txs txs, %s item where ojt.query_id = ? AND ojt.transaction_id = txs.transaction_id AND txs.gamma_id = item.gamma_id";
+
+ private final static String FIND_NEW_TX_CURRENTS =
+ "SELECT oj.id as item_id, txs.mod_type, txs.gamma_id, txs.transaction_id from osee_join_id oj, %s item, osee_txs txs where oj.query_id = ? and oj.id = item.%s and item.gamma_id = txs.gamma_id and txs.branch_id = ? order by oj.id desc, txs.transaction_id desc";
+
+ private static final String UPDATE_TX_CURRENT =
+ "update osee_txs set tx_current = ? where transaction_id = ? and gamma_id = ?";
+
+ private final int[] txIdsToDelete;
+ private final boolean force;
+ private boolean success;
+
+ public static interface PurgeTransactionListener {
+ void onPurgeTransactionSuccess(Collection<TransactionRecord> transactions);
+ }
+
+ private final Set<PurgeTransactionListener> listeners = new CopyOnWriteArraySet<PurgeTransactionListener>();
+ private Collection<TransactionRecord> changedTransactions;
+
+ public PurgeTransactionOperation(IOseeDatabaseService databaseService, boolean force, OperationLogger logger, int... txIdsToDelete) {
+ super(databaseService, String.format("Delete transactions: %s", Arrays.toString(txIdsToDelete)),
+ Activator.PLUGIN_ID, logger);
+ this.txIdsToDelete = txIdsToDelete;
+ this.force = force;
+ this.success = false;
+ }
+
+ public PurgeTransactionOperation(IOseeDatabaseService databaseService, boolean force, int... txIdsToDelete) {
+ super(databaseService, String.format("Delete transactions: %s", Arrays.toString(txIdsToDelete)),
+ Activator.PLUGIN_ID);
+ this.txIdsToDelete = txIdsToDelete;
+ this.force = force;
+ this.success = false;
+ }
+
+ public void addListener(PurgeTransactionListener listener) {
+ if (listener != null) {
+ listeners.add(listener);
+ }
+ }
+
+ public void removeListener(PurgeTransactionListener listener) {
+ if (listener != null) {
+ listeners.remove(listener);
+ }
+ }
+
+ @Override
+ protected void doTxWork(IProgressMonitor monitor, OseeConnection connection) throws OseeCoreException {
+ log();
+ log("Purging Transactions...");
+ Conditions.checkNotNull(txIdsToDelete, "transaction ids to delete");
+ Conditions.checkExpressionFailOnTrue(txIdsToDelete.length <= 0, "transaction ids to delete cannot be empty");
+
+ Arrays.sort(txIdsToDelete);
+
+ TransactionJoinQuery txsToDeleteQuery = JoinUtility.createTransactionJoinQuery();
+
+ Map<TransactionRecord, TransactionRecord> deleteToPreviousTx =
+ findPriorTransactions(monitor, txsToDeleteQuery, 0.20);
+
+ changedTransactions = deleteToPreviousTx.keySet();
+
+ txsToDeleteQuery.store(connection);
+
+ int txQueryId = txsToDeleteQuery.getQueryId();
+
+ try {
+ checkForModifiedBaselines(connection, force, txQueryId);
+
+ Map<Integer, IdJoinQuery> arts = findAffectedItems(connection, "art_id", "osee_artifact", txQueryId);
+ Map<Integer, IdJoinQuery> attrs = findAffectedItems(connection, "attr_id", "osee_attribute", txQueryId);
+ Map<Integer, IdJoinQuery> rels = findAffectedItems(connection, "rel_link_id", "osee_relation_link", txQueryId);
+ monitor.worked(calculateWork(0.20));
+
+ setChildBranchBaselineTxs(connection, monitor, deleteToPreviousTx, 0.20);
+ deleteItemEntriesForTransactions(connection, monitor, txQueryId, 0.20);
+
+ monitor.subTask("Remove Tx Rows");
+ List<Object[]> txsToDelete = new ArrayList<Object[]>();
+ for (int txId : txIdsToDelete) {
+ log(" Adding tx to list:" + txId);
+ txsToDelete.add(new Object[] {txId});
+ }
+ ConnectionHandler.runBatchUpdate(connection, DELETE_TX_DETAILS, txsToDelete);
+ ConnectionHandler.runBatchUpdate(connection, DELETE_TXS, txsToDelete);
+
+ monitor.subTask("Updating Previous Tx to Current");
+ List<Object[]> txsUpdate = new ArrayList<Object[]>();
+ computeNewTxCurrents(connection, txsUpdate, "art_id", "osee_artifact", arts);
+ computeNewTxCurrents(connection, txsUpdate, "attr_id", "osee_attribute", attrs);
+ computeNewTxCurrents(connection, txsUpdate, "rel_link_id", "osee_relation_link", rels);
+
+ ConnectionHandler.runBatchUpdate(connection, UPDATE_TX_CURRENT, txsUpdate);
+ monitor.worked(calculateWork(0.20));
+ success = true;
+ } finally {
+ clearJoin(connection, txsToDeleteQuery);
+ }
+ log("...done.");
+ }
+
+ @Override
+ protected void handleTxFinally(IProgressMonitor monitor) {
+ if (success && changedTransactions != null) {
+ for (PurgeTransactionListener listener : listeners) {
+ listener.onPurgeTransactionSuccess(changedTransactions);
+ }
+ }
+ changedTransactions = null;
+ }
+
+ private void computeNewTxCurrents(OseeConnection connection, Collection<Object[]> txsUpdate, String itemId, String tableName, Map<Integer, IdJoinQuery> affected) throws OseeCoreException {
+ String query = String.format(FIND_NEW_TX_CURRENTS, tableName, itemId);
+
+ for (Entry<Integer, IdJoinQuery> entry : affected.entrySet()) {
+ Integer branchId = entry.getKey();
+ IdJoinQuery joinQuery = entry.getValue();
+
+ IOseeStatement statement = ConnectionHandler.getStatement(connection);
+ try {
+ statement.runPreparedQuery(query, joinQuery.getQueryId(), branchId);
+ int previousItem = -1;
+ while (statement.next()) {
+ int currentItem = statement.getInt("item_id");
+
+ if (previousItem != currentItem) {
+ ModificationType modType = ModificationType.getMod(statement.getInt("mod_type"));
+ TxChange txCurrent = TxChange.getCurrent(modType);
+ txsUpdate.add(new Object[] {
+ txCurrent.getValue(),
+ statement.getInt("transaction_id"),
+ statement.getLong("gamma_id")});
+ previousItem = currentItem;
+ }
+ }
+ } finally {
+ statement.close();
+ }
+ joinQuery.delete(connection);
+ }
+ }
+
+ private void clearJoin(OseeConnection connection, TransactionJoinQuery txsToDeleteQuery) {
+ try {
+ if (connection != null && !connection.isClosed()) {
+ txsToDeleteQuery.delete(connection);
+ }
+ } catch (OseeCoreException ex) {
+ OseeLog.log(Activator.class, Level.SEVERE, ex.toString(), ex);
+ }
+ }
+
+ private Map<Integer, IdJoinQuery> findAffectedItems(OseeConnection connection, String itemId, String itemTable, int txQueryId) throws OseeCoreException {
+ Map<Integer, IdJoinQuery> items = new HashMap<Integer, IdJoinQuery>();
+
+ String query = String.format(SELECT_AFFECTED_ITEMS, itemId, itemTable);
+ IOseeStatement statement = ConnectionHandler.getStatement(connection);
+ try {
+ statement.runPreparedQuery(query, txQueryId);
+ while (statement.next()) {
+ Integer branchId = statement.getInt("branch_id");
+ IdJoinQuery joinId = items.get(branchId);
+ if (joinId == null) {
+ joinId = JoinUtility.createIdJoinQuery();
+ items.put(branchId, joinId);
+ }
+ Integer id = statement.getInt("item_id");
+ joinId.add(id);
+ }
+ } finally {
+ statement.close();
+ }
+
+ for (IdJoinQuery join : items.values()) {
+ join.store();
+ }
+ return items;
+ }
+
+ private Map<TransactionRecord, TransactionRecord> findPriorTransactions(IProgressMonitor monitor, TransactionJoinQuery txsToDeleteQuery, double workPercentage) throws OseeCoreException {
+ Map<TransactionRecord, TransactionRecord> deleteToPreviousTx =
+ new HashMap<TransactionRecord, TransactionRecord>();
+ double workStep = workPercentage / txIdsToDelete.length;
+ TransactionCache transactionCache = Activator.getOseeCachingService().getTransactionCache();
+ for (int index = 0; index < txIdsToDelete.length; index++) {
+ monitor.subTask(String.format("Fetching Previous Tx Info: [%d of %d]", index + 1, txIdsToDelete.length));
+ int fromTx = txIdsToDelete[index];
+ TransactionRecord fromTransaction = transactionCache.getOrLoad(fromTx);
+ TransactionRecord previousTransaction;
+ try {
+ previousTransaction = transactionCache.getPriorTransaction(fromTransaction);
+ } catch (TransactionDoesNotExist ex) {
+ throw new OseeArgumentException(
+ "You are trying to delete Transaction [%d] which is a baseline transaction. If your intent is to delete the Branch use the delete Branch Operation. \n\nNO TRANSACTIONS WERE DELETED.",
+ fromTx);
+ }
+ deleteToPreviousTx.put(fromTransaction, previousTransaction);
+
+ // Store transaction id(s) to delete - no need for gammas
+ txsToDeleteQuery.add(-1L, fromTx);
+ monitor.worked(calculateWork(workStep));
+ }
+ return deleteToPreviousTx;
+ }
+
+ private void deleteItemEntriesForTransactions(OseeConnection connection, IProgressMonitor monitor, int txsToDeleteQueryId, double workPercentage) throws OseeCoreException {
+ monitor.subTask("Deleting Tx Items");
+ List<Object[]> data = new ArrayList<Object[]>();
+ IOseeStatement chStmt = ConnectionHandler.getStatement(connection);
+ try {
+ chStmt.runPreparedQuery(SELECT_GAMMAS_FROM_TRANSACTION, txsToDeleteQueryId);
+ while (chStmt.next()) {
+ data.add(new Object[] {chStmt.getLong("gamma_id")});
+ }
+ } finally {
+ chStmt.close();
+ }
+ ConnectionHandler.runBatchUpdate(connection, DELETE_ARTIFACT_VERSIONS, data);
+ ConnectionHandler.runBatchUpdate(connection, DELETE_ATTRIBUTES, data);
+ ConnectionHandler.runBatchUpdate(connection, DELETE_RELATIONS, data);
+ monitor.worked(calculateWork(workPercentage));
+ }
+
+ private void setChildBranchBaselineTxs(OseeConnection connection, IProgressMonitor monitor, Map<TransactionRecord, TransactionRecord> deleteToPreviousTx, double workPercentage) throws OseeCoreException {
+ List<Object[]> data = new ArrayList<Object[]>();
+ monitor.subTask("Update Baseline Txs for Child Branches");
+ for (Entry<TransactionRecord, TransactionRecord> entry : deleteToPreviousTx.entrySet()) {
+ TransactionRecord previousTransaction = entry.getValue();
+ if (previousTransaction != null) {
+ int toDeleteTransaction = entry.getKey().getId();
+
+ data.add(new Object[] {
+ String.valueOf(toDeleteTransaction),
+ String.valueOf(previousTransaction.getId()),
+ "%" + toDeleteTransaction});
+ }
+ }
+ if (!data.isEmpty()) {
+ ConnectionHandler.runBatchUpdate(connection, UPDATE_TXS_DETAILS_COMMENT, data);
+ }
+ monitor.worked(calculateWork(workPercentage));
+ }
+
+ private void checkForModifiedBaselines(OseeConnection connection, boolean force, int queryId) throws OseeCoreException {
+ int transaction_id =
+ ConnectionHandler.runPreparedQueryFetchInt(connection, 0, TRANSACATION_GAMMA_IN_USE, queryId);
+ if (transaction_id > 0 && !force) {
+ throw new OseeCoreException(
+ "The Transaction %d holds a Gamma that is in use in other transactions. In order to delete this Transaction you will need to select the force check box.\n\nNO TRANSACTIONS WERE DELETED.",
+ transaction_id);
+ }
+ }
+} \ No newline at end of file

Back to the top