/* * Copyright (c) 2004, 2005, 2006 TADA AB - Taby Sweden * Distributed under the terms shown in the file COPYRIGHT * found in the root folder of this project or at * http://eng.tada.se/osprojects/COPYRIGHT.html */ package org.postgresql.pljava.internal; import java.sql.Connection; import java.sql.SQLException; import java.util.Iterator; import java.util.WeakHashMap; import java.util.logging.Logger; /** * @author Thomas Hallgren */ public class PgSavepoint implements java.sql.Savepoint { private static final WeakHashMap s_knownSavepoints = new WeakHashMap(); private long m_pointer; PgSavepoint(long pointer) { m_pointer = pointer; } public static PgSavepoint set(String name) throws SQLException { synchronized(Backend.THREADLOCK) { PgSavepoint sp = new PgSavepoint(_set(name)); s_knownSavepoints.put(sp, Boolean.TRUE); return sp; } } static PgSavepoint forId(int savepointId) { if(savepointId != 0) { synchronized(Backend.THREADLOCK) { Iterator itor = s_knownSavepoints.keySet().iterator(); while(itor.hasNext()) { PgSavepoint sp = (PgSavepoint)itor.next(); if(savepointId == _getId(sp.m_pointer)) return sp; } } } return null; } public int hashCode() { return this.getSavepointId(); } public boolean equals(Object o) { return (this == o); } public void release() throws SQLException { synchronized(Backend.THREADLOCK) { _release(m_pointer); s_knownSavepoints.remove(this); m_pointer = 0; } } public void rollback() throws SQLException { synchronized(Backend.THREADLOCK) { _rollback(m_pointer); s_knownSavepoints.remove(this); m_pointer = 0; } } public String getSavepointName() throws SQLException { synchronized(Backend.THREADLOCK) { return _getName(m_pointer); } } public int getSavepointId() { synchronized(Backend.THREADLOCK) { return _getId(m_pointer); } } public void onInvocationExit(Connection conn) throws SQLException { if(m_pointer == 0) return; Logger logger = Logger.getAnonymousLogger(); if(Backend.isReleaseLingeringSavepoints()) { logger.warning("Releasing savepoint '" + _getId(m_pointer) + "' since its lifespan exceeds that of the function where it was set"); conn.releaseSavepoint(this); } else { logger.warning("Rolling back to savepoint '" + _getId(m_pointer) + "' since its lifespan exceeds that of the function where it was set"); conn.rollback(this); } } private static native long _set(String name) throws SQLException; private static native void _release(long pointer) throws SQLException; private static native void _rollback(long pointer) throws SQLException; private static native String _getName(long pointer); private static native int _getId(long pointer); }