<commit_before>package com.postgrespro.sqlfiddle;

import java.io.*;
import java.sql.*;
import java.util.Locale;
import java.util.Map;
import java.util.regex.*;
import java.util.ResourceBundle;
import java.security.SecureRandom;
import java.time.format.DateTimeFormatter;
import java.text.SimpleDateFormat;
import org.json.*;

enum EnvironmentType { SeparateDb, DedicatedCluster };

public class PgExecutor implements AutoCloseable {

    public int MaxColumnSize = 1000;
    public int MaxRowCount = 1000;
    public int MaxResultSetCount = 10;
    public int MaxQueryDuration = 60; // seconds

    private StringBuilder log;
    private Connection adminConnection = null;
    private Connection adminNewDbConnection = null;
    private Connection userConnection = null;
    private String username;
    private String userPassword;
    private String connectionStringTemplate = null;
    private EnvironmentType envType;
    private String dedicatedDbUser = "postgres";
    private JSONObject dedicatedClusterProperties = null;
    private Pattern connectPattern = Pattern.compile("(?mi)\\A\\s*\\\\connect\\s+(.*)$");
    ResourceBundle i18nbundle = null;

    public PgExecutor(StringBuilder log) {
        this.log = log;
        this.i18nbundle = ResourceBundle.getBundle("i18n", Locale.getDefault());
    }

    private String generateUsername(String userName) {
        long mstime = System.currentTimeMillis();
        if (userName == null) userName = "user";
        userName = userName.replaceAll("(?i)[^0-9^a-z]", "_");
        return String.format("%s_%05d", userName != null  ? userName : "", mstime % 10000);
    }

    private String generatePassword() {
        String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        int len = 10;
        SecureRandom rnd = new SecureRandom();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++)
            sb.append(chars.charAt(rnd.nextInt(chars.length())));
        return sb.toString();
    }

    private Boolean execQuery(Connection conn, String sql) throws SQLException {
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            stmt.execute(sql);
        } finally {
            if (stmt != null) {
                stmt.close();
            }
        }
        return true;
    }

    private JSONArray getColumnNames(ResultSetMetaData meta) throws SQLException {
        JSONArray result = new JSONArray();
        int columnCount = meta.getColumnCount();
        for (int i = 1; i <= columnCount; i++) {
            result.put(meta.getColumnName(i));
        }
        return result;
    }

    private String clobToString(Clob clob) throws SQLException, IOException {
        Reader read = new InputStreamReader(clob.getAsciiStream());
        StringWriter w = new StringWriter();
        int c = -1;
        while ((c = read.read()) != -1) w.write(c);
        w.flush();
        return w.toString();
    }

    private String validateString(String arg) {
        if (arg == null)
            return arg;
        if (arg.length() > MaxColumnSize) return arg.substring(0, MaxColumnSize) + " ... " + "(truncated)";
        return arg;
    }

    private Object validateArray(Object arg) {
        return arg;
    }

    private JSONArray getRowData(ResultSet rs, ResultSetMetaData meta) throws SQLException, IOException {
        JSONArray result = new JSONArray();
        for (int i = 1; i <= meta.getColumnCount(); i++) {
            switch (meta.getColumnType(i)) {
                case java.sql.Types.TIMESTAMP:
                    result.put(rs.getTimestamp(i) != null ? new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(rs.getTimestamp(i)) : null);
                case java.sql.Types.TIME:
                    result.put(rs.getTime(i) != null ? new SimpleDateFormat("HH:mm:ss").format(rs.getTime(i)) : null);
                case java.sql.Types.DATE:
                    result.put(rs.getDate(i) != null ? new SimpleDateFormat("yyyy-MM-dd").format(rs.getDate(i)) : null);
                    break;
                case java.sql.Types.CLOB:
                    result.put(this.validateString(rs.getClob(i) != null ? this.clobToString(rs.getClob(i)) : null));
                    break;
                case java.sql.Types.ARRAY:
                    result.put(this.validateArray(rs.getArray(i) != null ? rs.getArray(i).getArray() : null));
                    break;
                case java.sql.Types.OTHER:<commit_msg>Fix erroneous output with TIMESTAMP columns<commit_after>package com.postgrespro.sqlfiddle;

import java.io.*;
import java.sql.*;
import java.util.Locale;
import java.util.Map;
import java.util.regex.*;
import java.util.ResourceBundle;
import java.security.SecureRandom;
import java.time.format.DateTimeFormatter;
import java.text.SimpleDateFormat;
import org.json.*;

enum EnvironmentType { SeparateDb, DedicatedCluster };

public class PgExecutor implements AutoCloseable {

    public int MaxColumnSize = 1000;
    public int MaxRowCount = 1000;
    public int MaxResultSetCount = 10;
    public int MaxQueryDuration = 60; // seconds

    private StringBuilder log;
    private Connection adminConnection = null;
    private Connection adminNewDbConnection = null;
    private Connection userConnection = null;
    private String username;
    private String userPassword;
    private String connectionStringTemplate = null;
    private EnvironmentType envType;
    private String dedicatedDbUser = "postgres";
    private JSONObject dedicatedClusterProperties = null;
    private Pattern connectPattern = Pattern.compile("(?mi)\\A\\s*\\\\connect\\s+(.*)$");
    ResourceBundle i18nbundle = null;

    public PgExecutor(StringBuilder log) {
        this.log = log;
        this.i18nbundle = ResourceBundle.getBundle("i18n", Locale.getDefault());
    }

    private String generateUsername(String userName) {
        long mstime = System.currentTimeMillis();
        if (userName == null) userName = "user";
        userName = userName.replaceAll("(?i)[^0-9^a-z]", "_");
        return String.format("%s_%05d", userName != null  ? userName : "", mstime % 10000);
    }

    private String generatePassword() {
        String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        int len = 10;
        SecureRandom rnd = new SecureRandom();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++)
            sb.append(chars.charAt(rnd.nextInt(chars.length())));
        return sb.toString();
    }

    private Boolean execQuery(Connection conn, String sql) throws SQLException {
        Statement stmt = null;
        try {
            stmt = conn.createStatement();
            stmt.execute(sql);
        } finally {
            if (stmt != null) {
                stmt.close();
            }
        }
        return true;
    }

    private JSONArray getColumnNames(ResultSetMetaData meta) throws SQLException {
        JSONArray result = new JSONArray();
        int columnCount = meta.getColumnCount();
        for (int i = 1; i <= columnCount; i++) {
            result.put(meta.getColumnName(i));
        }
        return result;
    }

    private String clobToString(Clob clob) throws SQLException, IOException {
        Reader read = new InputStreamReader(clob.getAsciiStream());
        StringWriter w = new StringWriter();
        int c = -1;
        while ((c = read.read()) != -1) w.write(c);
        w.flush();
        return w.toString();
    }

    private String validateString(String arg) {
        if (arg == null)
            return arg;
        if (arg.length() > MaxColumnSize) return arg.substring(0, MaxColumnSize) + " ... " + "(truncated)";
        return arg;
    }

    private Object validateArray(Object arg) {
        return arg;
    }

    private JSONArray getRowData(ResultSet rs, ResultSetMetaData meta) throws SQLException, IOException {
        JSONArray result = new JSONArray();
        for (int i = 1; i <= meta.getColumnCount(); i++) {
            switch (meta.getColumnType(i)) {
                case java.sql.Types.TIMESTAMP:
                    result.put(rs.getTimestamp(i) != null ? new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(rs.getTimestamp(i)) : null);
                    break;
                case java.sql.Types.TIME:
                    result.put(rs.getTime(i) != null ? new SimpleDateFormat("HH:mm:ss").format(rs.getTime(i)) : null);
                    break;
                case java.sql.Types.DATE:
                    result.put(rs.getDate(i) != null ? new SimpleDateFormat("yyyy-MM-dd").format(rs.getDate(i)) : null);
                    break;
                case java.sql.Types.CLOB:
                    result.put(this.validateString(rs.getClob(i) != null ? this.clobToString(rs.getClob(i)) : null));
                    break;
                case java.sql.Types.ARRAY:
                    result.put(this.validateArray(rs.getArray(i) != null ? rs.getArray(i).getArray() : null));
                    break;
                case java.sql.Types.OTHER:
{'fraction_non_alphanumeric': 0.11689738519006812, 'fraction_numerical': 0.00988793671720501, 'mean_word_length': 2.4325037707390647, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, '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': '2970746', 'n_tokens_mistral': 2672, 'n_tokens_neox': 2519, 'n_words': 610}