<commit_before>package com.axiomalaska.sos.injector.db;

import static com.axiomalaska.sos.injector.db.DatabaseSosInjectorHelper.getDouble;
import static com.axiomalaska.sos.injector.db.DatabaseSosInjectorHelper.makeDocument;
import static com.axiomalaska.sos.injector.db.DatabaseSosInjectorHelper.requireNonNull;
import static com.axiomalaska.sos.injector.db.DatabaseSosInjectorHelper.requireString;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import org.n52.sos.ioos.asset.SensorAsset;
import org.n52.sos.ioos.asset.StationAsset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.axiomalaska.cf4j.CFStandardNameUtil;
import com.axiomalaska.ioos.sos.GeomHelper;
import com.axiomalaska.ioos.sos.IoosSosConstants;
import com.axiomalaska.ioos.sos.IoosSosUtil;
import com.axiomalaska.jdbc.NamedParameterPreparedStatement;
import com.axiomalaska.phenomena.IoosParameterUtil;
import com.axiomalaska.phenomena.Phenomenon;
import com.axiomalaska.phenomena.UnitCreationException;
import com.axiomalaska.phenomena.UnitResolver;
import com.axiomalaska.sos.StationRetriever;
import com.axiomalaska.sos.data.SosSource;
import com.axiomalaska.sos.data.SosStation;
import com.axiomalaska.sos.exception.StationCreationException;
import com.axiomalaska.sos.injector.db.data.DatabasePhenomenon;
import com.axiomalaska.sos.injector.db.data.DatabaseSosSensor;
import com.axiomalaska.sos.injector.db.data.DatabaseSosStation;
import com.axiomalaska.sos.injector.db.exception.DatabaseSosInjectorStationCreationException;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.io.Files;

public class DatabaseStationRetriever implements StationRetriever {    
    private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseStationRetriever.class);
    private static final String GET_STATIONS_QUERY = "get_stations.sql";
    private static final String GET_STATION_SENSORS_QUERY = "get_station_sensors.sql";
    private static final String GET_SENSOR_PHENOMENA_QUERY = "get_sensor_phenomena.sql";
    
    private List<Statement> statements;
    private Connection connection;
    private Statement stationsStatement;
    private NamedParameterPreparedStatement stationSensorsStatement;
    private NamedParameterPreparedStatement sensorPhenomenaStatement;

    public DatabaseStationRetriever() {
        super();
        resetInstanceVars();
    }
    
    @Override
    public synchronized List<SosStation> getStations() throws StationCreationException {
        resetInstanceVars();

        try {
            return getStationsInternal();
        } catch (DatabaseSosInjectorStationCreationException e ) {
            throw new StationCreationException(e);
        } catch (SQLException e ) {
            throw new StationCreationException(e);            
        } finally {
            try {                
                for (Statement statement : statements) {
                    if (statement != null && !statement.isClosed()) {
                        statement.close();
                    }
                }
            } catch (SQLException e) {
                LOGGER.error("Error closing statement.");
            }
    
            try {
                //don't use lazy accessor getConnection() here, since it shouldn't be created if not already
                if (connection != null && !connection.isClosed()) {
                    connection.close();
                }
            } catch (SQLException e) {
                LOGGER.error("Error closing connection.");
            }

            //zero it out
            resetInstanceVars();
        }
    }

    private void resetInstanceVars() {
        statements = Lists.newArrayList();
        connection = null;
        stationsStatement = null;
        stationSensorsStatement = null;
        sensorPhenomenaStatement = null;        
    }
    
    private List<SosStation> getStationsInternal() throws DatabaseSosInjectorStationCreationException, SQLException {
        List<SosStation> stations = Lists.newArrayList();

        //get the query strings
        String getStationsQuery;
        String getSensorsQuery;
        String getSensorPhenomena;            
        try {
            getStationsQuery = Files.toString(new File(DatabaseSosInjectorConfig.instance().getQueryPath(),
                    GET_STATIONS_QUERY), Charsets.UTF_8);
        } catch (IOException e) {
            throw new DatabaseSosInjectorStationCreationException("Error getting " + GET_STATIONS_QUERY, e);
        }

        try {
            getSensorsQuery = Files.toString(new File(DatabaseSosInjectorConfig.instance().getQueryPath(),
                    GET_STATION_SENSORS_QUERY), Charsets.UTF_8);
        } catch (IOException e) {
            throw new DatabaseSosInjectorStationCreationException("Error getting " + GET_STATION_SENSORS_QUERY, e);
        }

        try {
            getSensorPhenomena = Files.toString(new File(DatabaseSosInjectorConfig.instance().getQueryPath(),
                    GET_SENSOR_PHENOMENA_QUERY), Charsets.UTF_8);
        } catch (IOException e) {
            throw new DatabaseSosInjectorStationCreationException("Error getting " + GET_SENSOR_PHENOMENA_QUERY, e);
        }

        //get the connection and statements
        try {
            stationsStatement = addStatement(getConnection().createStatement());
        } catch (Exception e) {
            throw new DatabaseSosInjectorStationCreationException("Error creating stations statement", e);
        }
        try {
            stationSensorsStatement = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(getConnection(), getSensorsQuery);
        } catch (Exception e) {
            throw new DatabaseSosInjectorStationCreationException("Error creating stations sensors statement", e);
        }
        addStatement(stationSensorsStatement);            
        try {
            sensorPhenomenaStatement = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(getConnection(), getSensorPhenomena);
        } catch (Exception e) {
            throw new DatabaseSosInjectorStationCreationException("Error creating sensor phenomena statement", e);
        }
        addStatement(sensorPhenomenaStatement);

        //execute the stations query<commit_msg>Log number of query parameters found<commit_after>package com.axiomalaska.sos.injector.db;

import static com.axiomalaska.sos.injector.db.DatabaseSosInjectorHelper.getDouble;
import static com.axiomalaska.sos.injector.db.DatabaseSosInjectorHelper.makeDocument;
import static com.axiomalaska.sos.injector.db.DatabaseSosInjectorHelper.requireNonNull;
import static com.axiomalaska.sos.injector.db.DatabaseSosInjectorHelper.requireString;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import org.n52.sos.ioos.asset.SensorAsset;
import org.n52.sos.ioos.asset.StationAsset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.axiomalaska.cf4j.CFStandardNameUtil;
import com.axiomalaska.ioos.sos.GeomHelper;
import com.axiomalaska.ioos.sos.IoosSosConstants;
import com.axiomalaska.ioos.sos.IoosSosUtil;
import com.axiomalaska.jdbc.NamedParameterPreparedStatement;
import com.axiomalaska.phenomena.IoosParameterUtil;
import com.axiomalaska.phenomena.Phenomenon;
import com.axiomalaska.phenomena.UnitCreationException;
import com.axiomalaska.phenomena.UnitResolver;
import com.axiomalaska.sos.StationRetriever;
import com.axiomalaska.sos.data.SosSource;
import com.axiomalaska.sos.data.SosStation;
import com.axiomalaska.sos.exception.StationCreationException;
import com.axiomalaska.sos.injector.db.data.DatabasePhenomenon;
import com.axiomalaska.sos.injector.db.data.DatabaseSosSensor;
import com.axiomalaska.sos.injector.db.data.DatabaseSosStation;
import com.axiomalaska.sos.injector.db.exception.DatabaseSosInjectorStationCreationException;
import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.io.Files;

public class DatabaseStationRetriever implements StationRetriever {    
    private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseStationRetriever.class);
    private static final String GET_STATIONS_QUERY = "get_stations.sql";
    private static final String GET_STATION_SENSORS_QUERY = "get_station_sensors.sql";
    private static final String GET_SENSOR_PHENOMENA_QUERY = "get_sensor_phenomena.sql";
    
    private List<Statement> statements;
    private Connection connection;
    private Statement stationsStatement;
    private NamedParameterPreparedStatement stationSensorsStatement;
    private NamedParameterPreparedStatement sensorPhenomenaStatement;

    public DatabaseStationRetriever() {
        super();
        resetInstanceVars();
    }
    
    @Override
    public synchronized List<SosStation> getStations() throws StationCreationException {
        resetInstanceVars();

        try {
            return getStationsInternal();
        } catch (DatabaseSosInjectorStationCreationException e ) {
            throw new StationCreationException(e);
        } catch (SQLException e ) {
            throw new StationCreationException(e);            
        } finally {
            try {                
                for (Statement statement : statements) {
                    if (statement != null && !statement.isClosed()) {
                        statement.close();
                    }
                }
            } catch (SQLException e) {
                LOGGER.error("Error closing statement.");
            }
    
            try {
                //don't use lazy accessor getConnection() here, since it shouldn't be created if not already
                if (connection != null && !connection.isClosed()) {
                    connection.close();
                }
            } catch (SQLException e) {
                LOGGER.error("Error closing connection.");
            }

            //zero it out
            resetInstanceVars();
        }
    }

    private void resetInstanceVars() {
        statements = Lists.newArrayList();
        connection = null;
        stationsStatement = null;
        stationSensorsStatement = null;
        sensorPhenomenaStatement = null;        
    }
    
    private List<SosStation> getStationsInternal() throws DatabaseSosInjectorStationCreationException, SQLException {
        List<SosStation> stations = Lists.newArrayList();

        //get the query strings
        String getStationsQuery;
        String getSensorsQuery;
        String getSensorPhenomena;            
        try {
            getStationsQuery = Files.toString(new File(DatabaseSosInjectorConfig.instance().getQueryPath(),
                    GET_STATIONS_QUERY), Charsets.UTF_8);
        } catch (IOException e) {
            throw new DatabaseSosInjectorStationCreationException("Error getting " + GET_STATIONS_QUERY, e);
        }

        try {
            getSensorsQuery = Files.toString(new File(DatabaseSosInjectorConfig.instance().getQueryPath(),
                    GET_STATION_SENSORS_QUERY), Charsets.UTF_8);
        } catch (IOException e) {
            throw new DatabaseSosInjectorStationCreationException("Error getting " + GET_STATION_SENSORS_QUERY, e);
        }

        try {
            getSensorPhenomena = Files.toString(new File(DatabaseSosInjectorConfig.instance().getQueryPath(),
                    GET_SENSOR_PHENOMENA_QUERY), Charsets.UTF_8);
        } catch (IOException e) {
            throw new DatabaseSosInjectorStationCreationException("Error getting " + GET_SENSOR_PHENOMENA_QUERY, e);
        }

        //get the connection and statements
        try {
            stationsStatement = addStatement(getConnection().createStatement());
        } catch (Exception e) {
            throw new DatabaseSosInjectorStationCreationException("Error creating stations statement", e);
        }

        try {
            stationSensorsStatement = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(getConnection(), getSensorsQuery);
        } catch (Exception e) {
            throw new DatabaseSosInjectorStationCreationException("Error creating stations sensors statement", e);
        }
        addStatement(stationSensorsStatement);
        LOGGER.debug("Found " + stationSensorsStatement.getParameterMetaData().getParameterCount() +
                " parameter(s) in stationSensorsStatement");        
        
        try {
            sensorPhenomenaStatement = NamedParameterPreparedStatement.createNamedParameterPreparedStatement(getConnection(), getSensorPhenomena);
        } catch (Exception e) {
            throw new DatabaseSosInjectorStationCreationException("Error creating sensor phenomena statement", e);
        }
        addStatement(sensorPhenomenaStatement);
        LOGGER.debug("Found " + sensorPhenomenaStatement.getParameterMetaData().getParameterCount() +
                " parameter(s) in sensorPhenomenaStatement");
        
        //execute the stations query
{'fraction_non_alphanumeric': 0.08045546482882612, 'fraction_numerical': 0.0014982395685070042, 'mean_word_length': 3.035671100362757, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2563930', 'n_tokens_mistral': 3626, 'n_tokens_neox': 3633, 'n_words': 668}