/******************************************************************************* * Copyright (c) 2012-2015 INRIA. * 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: * Generoso Pagano - initial API and implementation ******************************************************************************/ package fr.inria.soctrace.lib.storage.visitors; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import fr.inria.soctrace.lib.model.AnalysisResult; import fr.inria.soctrace.lib.model.Event; import fr.inria.soctrace.lib.model.EventParam; import fr.inria.soctrace.lib.model.EventParamType; import fr.inria.soctrace.lib.model.EventProducer; import fr.inria.soctrace.lib.model.EventType; import fr.inria.soctrace.lib.model.File; import fr.inria.soctrace.lib.model.IModelVisitor; import fr.inria.soctrace.lib.model.Tool; import fr.inria.soctrace.lib.model.Trace; import fr.inria.soctrace.lib.model.TraceParam; import fr.inria.soctrace.lib.model.TraceParamType; import fr.inria.soctrace.lib.model.TraceType; import fr.inria.soctrace.lib.model.utils.SoCTraceException; import fr.inria.soctrace.lib.storage.utils.SQLConstants.FramesocTable; /** * Base class for all model visitors. * * @author "Generoso Pagano <generoso.pagano@inria.fr>" */ public abstract class ModelVisitor implements IModelVisitor { /** * Prepared statement descriptor */ protected class PreparedStatementDescriptor { public FramesocTable table; public boolean visited; public PreparedStatement statement; public PreparedStatementDescriptor(PreparedStatement stm, FramesocTable t) { table = t; visited = false; statement = stm; } } /** * Prepared statement managed by this visitor */ protected Map<FramesocTable, PreparedStatementDescriptor> descriptors; /** * Base constructor. */ public ModelVisitor() { descriptors = new HashMap<FramesocTable, PreparedStatementDescriptor>(); } /** * Add a prepared statement descriptor for the given entity * * @param e * model entity * @param psd * prepared statement descriptor */ protected void addDescriptor(PreparedStatementDescriptor psd) { descriptors.put(psd.table, psd); } /** * Prepared statement descriptor getter * * @param e * model entity the descriptor is related with * @return the corresponding prepared statement descriptor */ protected PreparedStatementDescriptor getDescriptor(FramesocTable e) { return descriptors.get(e); } @Override public void executeBatches() throws SoCTraceException { PreparedStatementDescriptor p = null; try { Collection<PreparedStatementDescriptor> c = descriptors.values(); for (PreparedStatementDescriptor psd : c) { if (psd.visited) { p = psd; psd.statement.executeBatch(); } } postExecuteBatches(); } catch (SQLException e) { if (p != null) { System.err.println("Exception while visiting table " + p.table.toString()); } throw new SoCTraceException(e); } } @Override public void clearBatches() throws SoCTraceException { PreparedStatementDescriptor p = null; try { Collection<PreparedStatementDescriptor> c = descriptors.values(); for (PreparedStatementDescriptor psd : c) { p = psd; psd.visited = false; if (psd.statement != null) psd.statement.clearBatch(); } postClearBatches(); } catch (SQLException e) { if (p != null) { System.err.println("Exception while visiting table " + p.table.toString()); } throw new SoCTraceException(e); } } @Override public void close() throws SoCTraceException { PreparedStatementDescriptor p = null; try { Collection<PreparedStatementDescriptor> c = descriptors.values(); for (PreparedStatementDescriptor psd : c) { p = psd; if (psd.statement != null) psd.statement.close(); psd.statement = null; } postClose(); } catch (SQLException e) { if (p != null) { System.err.println("Exception while visiting table " + p.table.toString()); } throw new SoCTraceException(e); } } /* * Specific visitor "post" methods. Default implementation does nothing. Redefine if needed. */ protected void postExecuteBatches() throws SoCTraceException { } protected void postClearBatches() throws SoCTraceException { } protected void postClose() throws SoCTraceException { } /* * Visits */ @Override public void visit(Trace trace) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(TraceType traceType) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(TraceParam traceParam) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(TraceParamType traceParamType) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(Tool tool) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(Event event) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(AnalysisResult analysisResult) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(EventParam eventParam) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(EventType eventType) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(EventParamType eventParamType) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(EventProducer eventProducer) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } @Override public void visit(File file) throws SoCTraceException { throw new SoCTraceException("Visit not implemented in this visitor."); } } /* * Note about TIMESTAMP attributes (ANALYSIS_RESULT.DATE and TRACE.TRACING_DATE) * * 1. On MySQL the TIMESTAMP precision is only up to the 'second'. This is a well-known MySQL issue * (2013-02-14). * * 2. PreparedStatement.setTimestamp() works differently on different DBMS: - on MySQL keeps the * format YYYY-MM-DD hh:mm:ss - on SQLite converts to milliseconds format It is for this reason that * we use setString(), saving therefore the string value. */