All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eobjects.analyzer.storage.SqlDatabaseMap Maven / Gradle / Ivy

/**
 * AnalyzerBeans
 * Copyright (C) 2014 Neopost - Customer Information Management
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */
package org.eobjects.analyzer.storage;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.AbstractMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eobjects.analyzer.util.CollectionUtils2;

final class SqlDatabaseMap extends AbstractMap implements Map, SqlDatabaseCollection {

    private final Map _cache = CollectionUtils2. createCache(1000, 60).asMap();
    
    private final Connection _connection;
    private final String _tableName;
    private final PreparedStatement _getPreparedStatement;
    private final PreparedStatement _updatePreparedStatement;
    private final PreparedStatement _insertPreparedStatement;
    private volatile int _size;

    public SqlDatabaseMap(Connection connection, String tableName, String keyTypeName, String valueTypeName) {
        _connection = connection;
        _tableName = tableName;

        SqlDatabaseUtils.performUpdate(_connection, SqlDatabaseUtils.CREATE_TABLE_PREFIX + tableName + " (map_key "
                + keyTypeName + " PRIMARY KEY, map_value " + valueTypeName + ")");

        try {
            _getPreparedStatement = _connection.prepareStatement("SELECT map_value FROM " + _tableName
                    + " WHERE map_key = ?;");
            _updatePreparedStatement = _connection.prepareStatement("UPDATE " + _tableName
                    + " SET map_value = ? WHERE map_key = ?;");
            _insertPreparedStatement = _connection.prepareStatement("INSERT INTO  " + _tableName + " VALUES (?,?);");
        } catch (SQLException e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public int size() {
        return _size;
    }

    @SuppressWarnings("unchecked")
    @Override
    public synchronized V get(Object key) {
        V v = _cache.get(key);
        if (v != null) {
            return v;
        }

        ResultSet rs = null;
        try {
            _getPreparedStatement.setObject(1, key);
            rs = _getPreparedStatement.executeQuery();
            if (rs.next()) {
                return (V) rs.getObject(1);
            }
            return null;
        } catch (SQLException e) {
            throw new IllegalStateException(e);
        } finally {
            SqlDatabaseUtils.safeClose(rs, null);
        }
    }

    @Override
    public synchronized boolean containsKey(Object key) {
        if (_cache.containsKey(key)) {
            return true;
        }

        ResultSet rs = null;
        PreparedStatement st = null;
        try {
            st = _connection.prepareStatement("SELECT COUNT(*) FROM  " + _tableName + " WHERE map_key = ?");
            st.setObject(1, key);
            rs = st.executeQuery();
            if (rs.next()) {
                return rs.getInt(1) > 0;
            }
            return false;
        } catch (SQLException e) {
            throw new IllegalStateException(e);
        } finally {
            SqlDatabaseUtils.safeClose(rs, st);
        }
    }

    public synchronized V put(K key, V value) {
        try {
            final V v;
            if (containsKey(key)) {
                v = get(key);
                _updatePreparedStatement.setObject(1, value);
                _updatePreparedStatement.setObject(2, key);
                _updatePreparedStatement.executeUpdate();
            } else {
                _insertPreparedStatement.setObject(1, key);
                _insertPreparedStatement.setObject(2, value);
                _insertPreparedStatement.executeUpdate();
                _size++;
                v = null;
            }
            _cache.put(key, value);
            return v;
        } catch (SQLException e) {
            throw new IllegalStateException(e);
        }
    };

    @Override
    public synchronized V remove(Object key) {
        if (containsKey(key)) {
            V result = get(key);
            PreparedStatement st = null;
            try {
                st = _connection.prepareStatement("DELETE FROM " + _tableName + " WHERE map_key = ?");
                st.setObject(1, key);
                st.executeUpdate();
                _size--;
            } catch (SQLException e) {
                throw new IllegalStateException(e);
            } finally {
                SqlDatabaseUtils.safeClose(null, st);
            }
            _cache.remove(key);
            return result;
        }
        return null;
    }

    @Override
    public synchronized Set> entrySet() {
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            Set> result = new HashSet>();
            st = _connection.prepareStatement("SELECT map_key FROM " + _tableName + " ORDER BY map_key ASC;");
            rs = st.executeQuery();
            while (rs.next()) {
                @SuppressWarnings("unchecked")
                K key = (K) rs.getObject(1);
                result.add(new SqlDatabaseEntry(key));
            }
            return result;
        } catch (SQLException e) {
            throw new IllegalStateException(e);
        } finally {
            SqlDatabaseUtils.safeClose(rs, st);
        }
    }

    @Override
    public String getTableName() {
        return _tableName;
    }

    private class SqlDatabaseEntry implements Entry {

        private final K _key;

        public SqlDatabaseEntry(K key) {
            _key = key;
        }

        @Override
        public K getKey() {
            return _key;
        }

        @Override
        public V getValue() {
            return get(_key);
        }

        @Override
        public V setValue(V value) {
            return put(_key, value);
        }

        @Override
        public int hashCode() {
            return _key.hashCode();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        SqlDatabaseUtils.performUpdate(_connection, "DROP TABLE " + getTableName());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy