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

com.ibm.fhir.persistence.jdbc.dao.impl.CodeSystemDAOImpl Maven / Gradle / Ivy

There is a newer version: 4.11.1
Show newest version
/*
 * (C) Copyright IBM Corp. 2020, 2021
 *
 * SPDX-License-Identifier: Apache-2.0
 */

package com.ibm.fhir.persistence.jdbc.dao.impl;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.ibm.fhir.persistence.jdbc.dao.api.CodeSystemDAO;
import com.ibm.fhir.persistence.jdbc.exception.FHIRPersistenceDataAccessException;

/**
 * This DAO uses a connection provided to its constructor. It's therefore
 * assumed to be a short-lived object, created on-the-fly. Caching etc is handled
 * elsewhere...we're just doing JDBC stuff here.
 */
public class CodeSystemDAOImpl implements CodeSystemDAO {
    private static final Logger log = Logger.getLogger(CodeSystemDAOImpl.class.getName());
    private static final String CLASSNAME = CodeSystemDAOImpl.class.getName();

    private static final String SQL_CALL_ADD_CODE_SYSTEM_ID = "CALL %s.add_code_system(?, ?)";

    private static final String SQL_SELECT_ALL_CODE_SYSTEMS = "SELECT CODE_SYSTEM_ID, CODE_SYSTEM_NAME FROM CODE_SYSTEMS";

    private static final String SQL_SELECT_CODE_SYSTEM_ID = "SELECT CODE_SYSTEM_ID FROM CODE_SYSTEMS WHERE CODE_SYSTEM_NAME = ?";

    // The JDBC connection used by this DAO instance
    private final Connection connection;
    
    // name of the FHIR data schema
    private final String schemaName;

    /**
     * Constructs a DAO instance suitable for acquiring connections from a JDBC Datasource object.
     */
    public CodeSystemDAOImpl(Connection c, String schemaName) {
        this.connection = c;
        this.schemaName = schemaName;
    }

    /**
     * Provide subclasses with access to the {@link Connection}
     * @return
     */
    protected Connection getConnection() {
        return this.connection;
    }

    /**
     * Getter for the FHIR data schema
     * @return
     */
    protected String getSchemaName() {
        return this.schemaName;
    }

    @Override
    public Map readAllCodeSystems() throws FHIRPersistenceDataAccessException {
        final String METHODNAME = "readAllCodeSystems";
        log.entering(CLASSNAME, METHODNAME);

        ResultSet resultSet = null;
        String systemName;
        int systemId;
        Map systemMap = new HashMap<>();
        String errMsg = "Failure retrieving all code systems.";
        long dbCallStartTime;
        double dbCallDuration;

        dbCallStartTime = System.nanoTime();
        try (PreparedStatement stmt = connection.prepareStatement(SQL_SELECT_ALL_CODE_SYSTEMS)) {
            resultSet = stmt.executeQuery();
            dbCallDuration = (System.nanoTime()-dbCallStartTime)/1e6;
            if (log.isLoggable(Level.FINE)) {
                log.fine("DB read all code systems complete. executionTime=" + dbCallDuration + "ms");
            }
            while (resultSet.next()) {
                systemId = resultSet.getInt(1);
                systemName = resultSet.getString(2);
                systemMap.put(systemName, systemId);
            }
        }
        catch (Throwable e) {
            throw new FHIRPersistenceDataAccessException(errMsg,e);
        }
        finally {
            log.exiting(CLASSNAME, METHODNAME);
        }

        return systemMap;
    }

    /**
     * Calls a stored procedure to read the system contained in the passed Parameter in the Code_Systems table.
     * If it's not in the DB, it will be stored and a unique id will be returned.
     * @param systemName
     *
     * @return The generated id of the stored system.
     * @throws FHIRPersistenceDataAccessException
     */
    @Override
    public int readOrAddCodeSystem(String systemName) throws FHIRPersistenceDataAccessException   {
        final String METHODNAME = "readOrAddCodeSystem";
        log.entering(CLASSNAME, METHODNAME);

        int systemId;
        String stmtString;
        String errMsg = "Failure storing code system id: name=" + systemName;
        long dbCallStartTime;
        double dbCallDuration;

        try {
            stmtString = String.format(SQL_CALL_ADD_CODE_SYSTEM_ID, this.schemaName);
            try (CallableStatement stmt = connection.prepareCall(stmtString)) {
                stmt.setString(1, systemName);
                stmt.registerOutParameter(2, Types.INTEGER);
                dbCallStartTime = System.nanoTime();
                stmt.execute();
                dbCallDuration = (System.nanoTime()-dbCallStartTime)/1e6;
                if (log.isLoggable(Level.FINE)) {
                        log.fine("DB read code system id complete. executionTime=" + dbCallDuration + "ms");
                }
                systemId = stmt.getInt(2);
            }
        }
        catch (Throwable e) {
            throw new FHIRPersistenceDataAccessException(errMsg,e);
        }
        finally {
            log.exiting(CLASSNAME, METHODNAME);
        }
        return systemId;
    }

    /* (non-Javadoc)
     * @see com.ibm.fhir.persistence.jdbc.dao.api.CodeSystemDAO#readCodeSystemId(java.lang.String)
     */
    @Override
    public Integer readCodeSystemId(String codeSystem) throws FHIRPersistenceDataAccessException {
        final String METHODNAME = "readCodeSystemId";
        log.entering(CLASSNAME, METHODNAME);

        Integer result;
        ResultSet resultSet = null;
        String errMsg = "Failure retrieving code system. name=" + codeSystem;
        long dbCallStartTime;
        double dbCallDuration;

        try (PreparedStatement stmt = connection.prepareStatement(SQL_SELECT_CODE_SYSTEM_ID)) {
            stmt.setString(1, codeSystem);
            dbCallStartTime = System.nanoTime();
            resultSet = stmt.executeQuery();
            dbCallDuration = (System.nanoTime()-dbCallStartTime)/1e6;
            if (log.isLoggable(Level.FINE)) {
                log.fine("DB read code system complete. executionTime=" + dbCallDuration + "ms");
            }

            if (resultSet.next()) {
                result = resultSet.getInt(1);
            }
            else {
                result = null;
            }
        }
        catch (Throwable e) {
            throw new FHIRPersistenceDataAccessException(errMsg,e);
        }
        finally {
            log.exiting(CLASSNAME, METHODNAME);
        }

        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy