<commit_before>/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you under the Apache License, Version 2.0 (the            *
 * "License"); you may not use this file except in compliance   *
 * with the License.  You may obtain a copy of the License at   *
 *                                                              *
 *   http://www.apache.org/licenses/LICENSE-2.0                 *
 *                                                              *
 * Unless required by applicable law or agreed to in writing,   *
 * software distributed under the License is distributed on an  *
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
 * KIND, either express or implied.  See the License for the    *
 * specific language governing permissions and limitations      *
 * under the License.                                           *
 ****************************************************************/



package org.apache.james.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import java.io.File;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.DatabaseMetaData;

/**
 * Manages the persistence of the spam bayesian analysis corpus using a JDBC database.
 *
 * <p>This class is abstract to allow implementations to 
 * take advantage of different logging capabilities/interfaces in
 * different parts of the code.</p>

 * @version CVS $Revision$ $Date$
 * @since 2.3.0
 */

abstract public class JDBCBayesianAnalyzer
extends BayesianAnalyzer {
    
    /**
     *Public object representing a lock on database activity.
     */
    public final static String DATABASE_LOCK = "database lock";
    
    /**
     * An abstract method which child classes override to handle logging of
     * errors in their particular environments.
     *
     * @param errorString the error message generated
     */
    abstract protected void delegatedLog(String errorString);

    /**
     * The JDBCUtil helper class
     */
    private final JDBCUtil theJDBCUtil = new JDBCUtil() {
        protected void delegatedLog(String logString) {
            this.delegatedLog(logString);
        }
    };
    
    /**
     * Contains all of the sql strings for this component.
     */
    private SqlResources sqlQueries = new SqlResources();

    /**
     * Holds value of property sqlFileName.
     */
    private String sqlFileName;
    
    private File sqlFile;

    /**
     * Holds value of property sqlParameters.
     */
    private Map sqlParameters = new HashMap();

    /**
     * Holds value of property lastDatabaseUpdateTime.
     */
    private static long lastDatabaseUpdateTime;
    
    /**
     * Getter for property sqlFileName.
     * @return Value of property sqlFileName.
     */
    public String getSqlFileName() {

        return this.sqlFileName;
    }

    /**
     * Setter for property sqlFileName.
     * @param sqlFileName New value of property sqlFileName.
     */
    public void setSqlFileName(String sqlFileName) {

        this.sqlFileName = sqlFileName;
    }

    /**
     * Getter for property sqlParameters.
     * @return Value of property sqlParameters.
     */
    public Map getSqlParameters() {

        return this.sqlParameters;
    }

    /**
     * Setter for property sqlParameters.
     * @param sqlParameters New value of property sqlParameters.
     */
    public void setSqlParameters(Map sqlParameters) {

        this.sqlParameters = sqlParameters;
    }

    /**
     * Getter for static lastDatabaseUpdateTime.
     * @return Value of property lastDatabaseUpdateTime.
     */
    public static long getLastDatabaseUpdateTime() {

        return lastDatabaseUpdateTime;
    }

    /**
     * Sets static lastDatabaseUpdateTime to System.currentTimeMillis().
     */
    public static void touchLastDatabaseUpdateTime() {

        lastDatabaseUpdateTime = System.currentTimeMillis();
    }

    /**
     * Default constructor.
     */
    public JDBCBayesianAnalyzer() {
    }
        
    /**
     * Loads the token frequencies from the database.
     * @param conn The connection for accessing the database
     * @throws SQLException If a database error occurs
     */
    public void loadHamNSpam(Connection conn)
    throws java.sql.SQLException {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try {
            pstmt = conn.prepareStatement(sqlQueries.getSqlString("selectHamTokens", true));
            rs = pstmt.executeQuery();
            
            Map ham = getHamTokenCounts();
            while (rs.next()) {
                String token = rs.getString(1);
                int count = rs.getInt(2);
                // to reduce memory, use the token only if the count is > 1
                if (count > 1) {
                    ham.put(token, new Integer(count));
                }
            }
            //Verbose.
            delegatedLog("Ham tokens count: " + ham.size());
            
            rs.close();
            pstmt.close();
                        
            //Get the spam tokens/counts.
            pstmt = conn.prepareStatement(sqlQueries.getSqlString("selectSpamTokens", true));
            rs = pstmt.executeQuery();
            
            Map spam = getSpamTokenCounts();
            while (rs.next()) {
                String token = rs.getString(1);
                int count = rs.getInt(2);
                // to reduce memory, use the token only if the count is > 1
                if (count > 1) {
                    spam.put(token, new Integer(count));
                }
            }
            
            //Verbose.
            delegatedLog("Spam tokens count: " + spam.size());
            
            rs.close();
            pstmt.close();
                        
            //Get the ham/spam message counts.
            pstmt = conn.prepareStatement(sqlQueries.getSqlString("selectMessageCounts", true));
            rs = pstmt.executeQuery();
            if (rs.next()) {
                setHamMessageCount(rs.getInt(1));
                setSpamMessageCount(rs.getInt(2));
            }
            
            rs.close();
            pstmt.close();
            
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (java.sql.SQLException se) {
                }
                
                rs = null;
            }
            
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (java.sql.SQLException se) {
                }
                
                pstmt = null;
            }
        }
    }
    
    /**
     * Updates the database with new "ham" token frequencies.
     * @param conn The connection for accessing the database
     * @throws SQLException If a database error occurs
     */
    public void updateHamTokens(Connection conn)
    throws java.sql.SQLException {
        updateTokens(conn, getHamTokenCounts(),
                sqlQueries.getSqlString("insertHamToken", true),
                sqlQueries.getSqlString("updateHamToken", true));
        
        setMessageCount(conn, sqlQueries.getSqlString("updateHamMessageCounts", true), getHamMessageCount());
    }
    
    /**
     * Updates the database with new "spam" token frequencies.
     * @param conn The connection for accessing the database
     * @throws SQLException If a database error occurs
     */
    public void updateSpamTokens(Connection conn)
    throws java.sql.SQLException {
         updateTokens(conn, getSpamTokenCounts(),
                sqlQueries.getSqlString("insertSpamToken", true),
                sqlQueries.getSqlString("updateSpamToken", true));
       
        setMessageCount(conn, sqlQueries.getSqlString("updateSpamMessageCounts", true), getSpamMessageCount());
    }
    
    /**
     * Reset all trained data
     * 
     * @param conn The connection for accessing the database
     * @throws SQLException If a dtabase error occours
     */
    public void resetData(Connection conn) throws SQLException {
    deleteData(conn,sqlQueries.getSqlString("deleteHamTokens",true));
    deleteData(conn,sqlQueries.getSqlString("deleteSpamTokens",true));
    deleteData(conn,sqlQueries.getSqlString("deleteMessageCounts",true));
    }
    
    private void setMessageCount(Connection conn, String sqlStatement, int count)
    throws java.sql.SQLException {
        PreparedStatement init = null;
        PreparedStatement update = null;
        
        try {
            //set the ham/spam message counts.
            init = conn.prepareStatement(sqlQueries.getSqlString("initializeMessageCounts", true));
            update = conn.prepareStatement(sqlStatement);
            
            update.setInt(1, count);
            
            if (update.executeUpdate() == 0) {
                init.executeUpdate();
                update.executeUpdate();
            }<commit_msg>Fix format.<commit_after>/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you under the Apache License, Version 2.0 (the            *
 * "License"); you may not use this file except in compliance   *
 * with the License.  You may obtain a copy of the License at   *
 *                                                              *
 *   http://www.apache.org/licenses/LICENSE-2.0                 *
 *                                                              *
 * Unless required by applicable law or agreed to in writing,   *
 * software distributed under the License is distributed on an  *
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
 * KIND, either express or implied.  See the License for the    *
 * specific language governing permissions and limitations      *
 * under the License.                                           *
 ****************************************************************/



package org.apache.james.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import java.io.File;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.DatabaseMetaData;

/**
 * Manages the persistence of the spam bayesian analysis corpus using a JDBC database.
 *
 * <p>This class is abstract to allow implementations to 
 * take advantage of different logging capabilities/interfaces in
 * different parts of the code.</p>

 * @version CVS $Revision$ $Date$
 * @since 2.3.0
 */

abstract public class JDBCBayesianAnalyzer
extends BayesianAnalyzer {
    
    /**
     *Public object representing a lock on database activity.
     */
    public final static String DATABASE_LOCK = "database lock";
    
    /**
     * An abstract method which child classes override to handle logging of
     * errors in their particular environments.
     *
     * @param errorString the error message generated
     */
    abstract protected void delegatedLog(String errorString);

    /**
     * The JDBCUtil helper class
     */
    private final JDBCUtil theJDBCUtil = new JDBCUtil() {
        protected void delegatedLog(String logString) {
            this.delegatedLog(logString);
        }
    };
    
    /**
     * Contains all of the sql strings for this component.
     */
    private SqlResources sqlQueries = new SqlResources();

    /**
     * Holds value of property sqlFileName.
     */
    private String sqlFileName;
    
    private File sqlFile;

    /**
     * Holds value of property sqlParameters.
     */
    private Map sqlParameters = new HashMap();

    /**
     * Holds value of property lastDatabaseUpdateTime.
     */
    private static long lastDatabaseUpdateTime;
    
    /**
     * Getter for property sqlFileName.
     * @return Value of property sqlFileName.
     */
    public String getSqlFileName() {

        return this.sqlFileName;
    }

    /**
     * Setter for property sqlFileName.
     * @param sqlFileName New value of property sqlFileName.
     */
    public void setSqlFileName(String sqlFileName) {

        this.sqlFileName = sqlFileName;
    }

    /**
     * Getter for property sqlParameters.
     * @return Value of property sqlParameters.
     */
    public Map getSqlParameters() {

        return this.sqlParameters;
    }

    /**
     * Setter for property sqlParameters.
     * @param sqlParameters New value of property sqlParameters.
     */
    public void setSqlParameters(Map sqlParameters) {

        this.sqlParameters = sqlParameters;
    }

    /**
     * Getter for static lastDatabaseUpdateTime.
     * @return Value of property lastDatabaseUpdateTime.
     */
    public static long getLastDatabaseUpdateTime() {

        return lastDatabaseUpdateTime;
    }

    /**
     * Sets static lastDatabaseUpdateTime to System.currentTimeMillis().
     */
    public static void touchLastDatabaseUpdateTime() {

        lastDatabaseUpdateTime = System.currentTimeMillis();
    }

    /**
     * Default constructor.
     */
    public JDBCBayesianAnalyzer() {
    }
        
    /**
     * Loads the token frequencies from the database.
     * @param conn The connection for accessing the database
     * @throws SQLException If a database error occurs
     */
    public void loadHamNSpam(Connection conn)
    throws java.sql.SQLException {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try {
            pstmt = conn.prepareStatement(sqlQueries.getSqlString("selectHamTokens", true));
            rs = pstmt.executeQuery();
            
            Map ham = getHamTokenCounts();
            while (rs.next()) {
                String token = rs.getString(1);
                int count = rs.getInt(2);
                // to reduce memory, use the token only if the count is > 1
                if (count > 1) {
                    ham.put(token, new Integer(count));
                }
            }
            //Verbose.
            delegatedLog("Ham tokens count: " + ham.size());
            
            rs.close();
            pstmt.close();
                        
            //Get the spam tokens/counts.
            pstmt = conn.prepareStatement(sqlQueries.getSqlString("selectSpamTokens", true));
            rs = pstmt.executeQuery();
            
            Map spam = getSpamTokenCounts();
            while (rs.next()) {
                String token = rs.getString(1);
                int count = rs.getInt(2);
                // to reduce memory, use the token only if the count is > 1
                if (count > 1) {
                    spam.put(token, new Integer(count));
                }
            }
            
            //Verbose.
            delegatedLog("Spam tokens count: " + spam.size());
            
            rs.close();
            pstmt.close();
                        
            //Get the ham/spam message counts.
            pstmt = conn.prepareStatement(sqlQueries.getSqlString("selectMessageCounts", true));
            rs = pstmt.executeQuery();
            if (rs.next()) {
                setHamMessageCount(rs.getInt(1));
                setSpamMessageCount(rs.getInt(2));
            }
            
            rs.close();
            pstmt.close();
            
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (java.sql.SQLException se) {
                }
                
                rs = null;
            }
            
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (java.sql.SQLException se) {
                }
                
                pstmt = null;
            }
        }
    }
    
    /**
     * Updates the database with new "ham" token frequencies.
     * @param conn The connection for accessing the database
     * @throws SQLException If a database error occurs
     */
    public void updateHamTokens(Connection conn)
    throws java.sql.SQLException {
        updateTokens(conn, getHamTokenCounts(),
                sqlQueries.getSqlString("insertHamToken", true),
                sqlQueries.getSqlString("updateHamToken", true));
        
        setMessageCount(conn, sqlQueries.getSqlString("updateHamMessageCounts", true), getHamMessageCount());
    }
    
    /**
     * Updates the database with new "spam" token frequencies.
     * @param conn The connection for accessing the database
     * @throws SQLException If a database error occurs
     */
    public void updateSpamTokens(Connection conn)
    throws java.sql.SQLException {
         updateTokens(conn, getSpamTokenCounts(),
                sqlQueries.getSqlString("insertSpamToken", true),
                sqlQueries.getSqlString("updateSpamToken", true));
       
        setMessageCount(conn, sqlQueries.getSqlString("updateSpamMessageCounts", true), getSpamMessageCount());
    }
    
    /**
     * Reset all trained data
     * 
     * @param conn The connection for accessing the database
     * @throws SQLException If a dtabase error occours
     */
    public void resetData(Connection conn) throws SQLException {
        deleteData(conn,sqlQueries.getSqlString("deleteHamTokens",true));
        deleteData(conn,sqlQueries.getSqlString("deleteSpamTokens",true));
        deleteData(conn,sqlQueries.getSqlString("deleteMessageCounts",true));
    }
    
    private void setMessageCount(Connection conn, String sqlStatement, int count)
    throws java.sql.SQLException {
        PreparedStatement init = null;
        PreparedStatement update = null;
        
        try {
            //set the ham/spam message counts.
            init = conn.prepareStatement(sqlQueries.getSqlString("initializeMessageCounts", true));
            update = conn.prepareStatement(sqlStatement);
            
            update.setInt(1, count);
            
            if (update.executeUpdate() == 0) {
                init.executeUpdate();
                update.executeUpdate();
            }
{'fraction_non_alphanumeric': 0.09836682067261202, 'fraction_numerical': 0.0020414741592349843, 'mean_word_length': 1.8625249884668615, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '528140', 'n_tokens_mistral': 4712, 'n_tokens_neox': 4550, 'n_words': 1339}