<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.Common;
using Npgsql;
using log4net;
using System.Reflection;
using System.Runtime.Serialization;

namespace TabMon.LogPoller
{

    public struct ViewPath
    {
        public string workbook;
        public string view;

        public string ip;

        public static ViewPath make(string workbook, string view, string ip)
        {
            var p = new ViewPath();
            p.workbook = workbook;
            p.view = view;
            p.ip = ip;
            return p;
        }

        public bool isEmpty() { return workbook == null && view == null; }

        public static ViewPath Empty = make(null, null, null);
    }

    /// <summary>
    /// Interface class for the tableau repo
    /// </summary>
    public interface ITableauRepoConn : IDisposable
    {
        ViewPath getViewPathForVizQLSessionId(string vizQLSessionId, DateTime timestamp);

    }

    public class Tableau9RepoConn : ITableauRepoConn
    {

        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private NpgsqlConnection connection;
        private object readLock = new object();

        public Tableau9RepoConn(string host, int port, string username, string password, string database)
        {
            var connectionString =
                new NpgsqlConnectionStringBuilder()
                {
                    Host = host,
                    Port = port,
                    UserName = username,
                    Password = password,
                    Database = database
                };

            Log.Info("Connecting to Tableau Repo PostgreSQL:" + host);
            connection = new NpgsqlConnection(connectionString);
            OpenConnection();
            Log.Info("Connected to Tableau Repo...");

        }

        /// <summary>
        /// Open the database connection.
        /// </summary>
        void OpenConnection()
        {
            connection.Open();

            if (!IsConnectionOpen())
            {
                throw new DbConnectionException("Could not open connection to Tableau PostgreSQL repository.");
            }
        }


        /// <summary>
        /// Close the database connection.
        /// </summary>
        void CloseConnection()
        {
            connection.Close();
        }

        /// <summary>
        /// Returns true if database connection is in an open state.
        /// </summary>
        /// <returns></returns>
        bool IsConnectionOpen()
        {
            return connection.State == ConnectionState.Open;
        }

        IDbConnection reconnectIfNeeded()
        {
            if (IsConnectionOpen()) return connection;
            connection.Close();
            OpenConnection();
            return connection;
        }


        public ViewPath getViewPathForVizQLSessionId(string vizQLSessionId, DateTime timestamp)
        {
            if (String.IsNullOrWhiteSpace(vizQLSessionId)) return ViewPath.Empty;

            lock (readLock)
            {

                reconnectIfNeeded();

                using (var cmd = connection.CreateCommand())
                {

                    cmd.Connection = connection;
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = "SELECT * FROM http_requests WHERE vizql_session=@vizql_session_id AND created_at < @timestamp ORDER BY created_at DESC LIMIT 1";
<commit_msg>fix: remove the star from the http_requests table query to speed up the lookups<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.Common;
using Npgsql;
using log4net;
using System.Reflection;
using System.Runtime.Serialization;

namespace TabMon.LogPoller
{

    public struct ViewPath
    {
        public string workbook;
        public string view;

        public string ip;

        public static ViewPath make(string workbook, string view, string ip)
        {
            var p = new ViewPath();
            p.workbook = workbook;
            p.view = view;
            p.ip = ip;
            return p;
        }

        public bool isEmpty() { return workbook == null && view == null; }

        public static ViewPath Empty = make(null, null, null);
    }

    /// <summary>
    /// Interface class for the tableau repo
    /// </summary>
    public interface ITableauRepoConn : IDisposable
    {
        ViewPath getViewPathForVizQLSessionId(string vizQLSessionId, DateTime timestamp);

    }

    public class Tableau9RepoConn : ITableauRepoConn
    {

        private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private NpgsqlConnection connection;
        private object readLock = new object();

        public Tableau9RepoConn(string host, int port, string username, string password, string database)
        {
            var connectionString =
                new NpgsqlConnectionStringBuilder()
                {
                    Host = host,
                    Port = port,
                    UserName = username,
                    Password = password,
                    Database = database
                };

            Log.Info("Connecting to Tableau Repo PostgreSQL:" + host);
            connection = new NpgsqlConnection(connectionString);
            OpenConnection();
            Log.Info("Connected to Tableau Repo...");

        }

        /// <summary>
        /// Open the database connection.
        /// </summary>
        void OpenConnection()
        {
            connection.Open();

            if (!IsConnectionOpen())
            {
                throw new DbConnectionException("Could not open connection to Tableau PostgreSQL repository.");
            }
        }


        /// <summary>
        /// Close the database connection.
        /// </summary>
        void CloseConnection()
        {
            connection.Close();
        }

        /// <summary>
        /// Returns true if database connection is in an open state.
        /// </summary>
        /// <returns></returns>
        bool IsConnectionOpen()
        {
            return connection.State == ConnectionState.Open;
        }

        IDbConnection reconnectIfNeeded()
        {
            if (IsConnectionOpen()) return connection;
            connection.Close();
            OpenConnection();
            return connection;
        }


        public ViewPath getViewPathForVizQLSessionId(string vizQLSessionId, DateTime timestamp)
        {
            if (String.IsNullOrWhiteSpace(vizQLSessionId)) return ViewPath.Empty;

            lock (readLock)
            {

                reconnectIfNeeded();

                using (var cmd = connection.CreateCommand())
                {

                    cmd.Connection = connection;
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = "SELECT currentsheet, user_ip FROM http_requests WHERE vizql_session=@vizql_session_id AND created_at < @timestamp ORDER BY created_at DESC LIMIT 1";

{'fraction_non_alphanumeric': 0.08367683429513603, 'fraction_numerical': 0.0010992030777686177, 'mean_word_length': 1.7416195856873824, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 23, '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': '6488074', 'n_tokens_mistral': 1821, 'n_tokens_neox': 1738, 'n_words': 495}