2025년 3월 20일 목요일

csv load 2.5

class CsvProcessor:
    def __init__(self, file_name, dict_fields):
        self.file_name = file_name
        self.dict_fields = dict_fields.split(",")  # 필드명은 쉼표로 분리
        self.data_list = []

    def process_csv(self):
        try:
            # 파일을 열고 처리
            csv_file = open(self.file_name, "r")
            for line in csv_file:
                columns = line.strip().split(",")
                entry = {self.dict_fields[i]: columns[i] for i in range(len(self.dict_fields))}
                self.data_list.append(entry)
            csv_file.close()
        except Exception as e:
            # 새로운 Exception 발생 (원래의 Exception 포함)
            raise RuntimeError("Failed to process the CSV file (%s): %s" % (self.file_name, str(e)))

    def print_data(self):
        for entry in self.data_list:
            print(entry)

# 사용 예시
file_name = "./resources/data.csv"  # CSV 파일 경로
dict_fields = "no,display,amount"

try:
    processor = CsvProcessor(file_name, dict_fields)
    processor.process_csv()
    processor.print_data()
except RuntimeError as e:
    print("Caught RuntimeError: %s" % str(e))

csv 파일 처리

import random  # 랜덤 선택을 위한 모듈

class CsvProcessor:
    def __init__(self, file_name, dict_fields):
        self.file_name = file_name
        self.dict_fields = dict_fields.split(",")  # 필드명은 쉼표로 분리
        self.data_list = []

    def process_csv(self):
        try:
            with open(self.file_name, "r") as csv_file:
                for line in csv_file:
                    # 각 줄을 쉼표로 분리하여 열 데이터 추출
                    columns = line.strip().split(",")
                    # dict_fields를 기준으로 딕셔너리 생성
                    entry = {self.dict_fields[i]: columns[i] for i in range(len(self.dict_fields))}
                    # 숫자 변환 가능하면 정수로 변환
                    for key in entry:
                        if entry[key].isdigit():
                            entry[key] = int(entry[key])
                    self.data_list.append(entry)
        except Exception as e:
            print(f"Error while processing the file: {e}")

    def get_random_entry(self):
        # data_list에서 랜덤으로 하나의 딕셔너리를 반환
        if not self.data_list:
            print("Data list is empty. Please process the CSV file first.")
            return None
        return random.choice(self.data_list)

# 사용 예시
file_name = "./resources/data.csv"  # CSV 파일 경로
dict_fields = "no,display,amount"   # dict 항목명

processor = CsvProcessor(file_name, dict_fields)
processor.process_csv()

# 랜덤 딕셔너리 가져오기
random_entry = processor.get_random_entry()
print(random_entry)

2025년 3월 14일 금요일

Grinder jython 2


class RequestBuilder:
    def __init__(self, grinder_request, logger):
        self.grinder_request = grinder_request
        self.logger = logger
        self.base_url = ""
        self.request_url = ""
        self.port = 80
        self.parameters = {}
        self.cookies = {}

    def set_base_url(self, base_url):
        self.base_url = base_url
        return self

    def set_request_url(self, request_url):
        self.request_url = request_url
        return self

    def set_port(self, port):
        self.port = port
        return self

    def set_parameters(self, params):
        self.parameters.update(params)
        return self

    def set_cookies(self, cookies):
        self.cookies.update(cookies)
        return self

    def build_full_url(self, overrides={}):
        # 호출 시 덮어쓸 속성 가져오기
        active_port = overrides.get("port", self.port)
        active_parameters = overrides.get("parameters", self.parameters)
        param_string = "&".join([f"{k}={v}" for k, v in active_parameters.items()])
        return f"{self.base_url}:{active_port}{self.request_url}?{param_string}"

    def execute_get(self, overrides={}):
        # 동적으로 속성을 덮어쓴 URL 생성
        full_url = self.build_full_url(overrides)
        self.logger.info(f"GET 요청 URL: {full_url}")

        # GET 요청 실행
        response = self.grinder_request.GET(full_url)
        self.logger.info(f"GET 응답: {response.text}")
        return response


from net.grinder.script.Grinder import grinder
from net.grinder.plugin.http import HTTPRequest
from common_module import RequestBuilder

# nGrinder의 HTTP Request 객체 생성
http_request = HTTPRequest()

# Logger 객체 생성
logger = grinder.logger

# RequestBuilder 인스턴스 생성
builder = RequestBuilder(http_request, logger)
builder.set_base_url("http://example.com") \
       .set_request_url("/api/test") \
       .set_port(8080) \
       .set_parameters({"key1": "value1", "key2": "value2"}) \
       .set_cookies({"SESSION": "abc123"})

# 기본 속성으로 GET 요청 실행
get_response = builder.execute_get()
print(f"GET Response: {get_response.text}")

# 덮어쓰기 속성으로 GET 요청 실행
overrides = {
    "port": 9090,
    "parameters": {"key3": "value3", "key4": "value4"}
}
get_response_with_overrides = builder.execute_get(overrides)
print(f"GET Response with Overrides: {get_response_with_overrides.text}")

grinder jython


class RequestBuilder:
    def __init__(self, grinder_request, logger):
        self.grinder_request = grinder_request  # nGrinder의 HTTPRequest 객체
        self.logger = logger  # nGrinder의 Logger 객체
        self.base_url = ""
        self.request_url = ""
        self.port = 80
        self.parameters = {}
        self.cookies = {}

    def set_base_url(self, base_url):
        self.base_url = base_url
        return self

    def set_request_url(self, request_url):
        self.request_url = request_url
        return self

    def set_port(self, port):
        self.port = port
        return self

    def set_parameters(self, params):
        self.parameters.update(params)
        return self

    def set_cookies(self, cookies):
        self.cookies.update(cookies)
        return self

    def build_full_url(self):
        param_string = "&".join([f"{k}={v}" for k, v in self.parameters.items()])
        return f"{self.base_url}:{self.port}{self.request_url}?{param_string}"

    def execute_get(self):
        full_url = self.build_full_url()
        self.logger.info(f"GET 요청 URL: {full_url}")  # 로그 추가

        response = self.grinder_request.GET(full_url)
        self.logger.info(f"GET 응답: {response.text}")  # 응답 로그 기록
        return response

    def execute_post(self):
        full_url = f"{self.base_url}:{self.port}{self.request_url}"
        self.logger.info(f"POST 요청 URL: {full_url}")  # 로그 추가
        self.logger.info(f"POST 요청 데이터: {self.parameters}")  # 요청 데이터 로그

        response = self.grinder_request.POST(full_url, self.parameters)
        self.logger.info(f"POST 응답: {response.text}")  # 응답 로그 기록
        return response

from net.grinder.script.Grinder import grinder
from net.grinder.plugin.http import HTTPRequest
from common_module import RequestBuilder

# nGrinder의 HTTP Request 객체 생성
http_request = HTTPRequest()

# Logger 객체 생성
logger = grinder.logger

# RequestBuilder 인스턴스 생성
builder = RequestBuilder(http_request, logger)
builder.set_base_url("http://example.com") \
       .set_request_url("/api/test") \
       .set_port(8080) \
       .set_parameters({"key1": "value1", "key2": "value2"}) \
       .set_cookies({"SESSION": "abc123"})

# GET 요청 실행 및 로그 출력
get_response = builder.execute_get()
print(f"GET Response: {get_response.text}")

# POST 요청 실행 및 로그 출력
post_response = builder.execute_post()
print(f"POST Response: {post_response.text}")

java run



@echo off
"C:\some\java.exe" ^
      -Djava.io.tmpdir=C:\sometemp ^
       -jar C:\somewar\some.war ^
       --port=7070
pause

2025년 3월 11일 화요일

sql formmater with mybatis

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import com.github.vertical_blank.sqlformatter.SqlFormatter;

import java.util.List;
import java.util.Properties;

@Intercepts({
    @Signature(
        type = Executor.class,
        method = "query",
        args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
    )
})
public class ParameterReplacingInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 쿼리 정보 가져오기
        Object[] args = invocation.getArgs();
        MappedStatement mappedStatement = (MappedStatement) args[0];
        Object parameterObject = args[1];
        BoundSql boundSql = mappedStatement.getBoundSql(parameterObject);

        // 원본 SQL 및 파라미터 처리
        String modifiedSql = replacePlaceholdersWithParameterNames(boundSql);

        // 로그 출력
        System.out.println("Modified SQL:");
        System.out.println(modifiedSql);

        // 실제 실행
        return invocation.proceed();
    }

    private String replacePlaceholdersWithParameterNames(BoundSql boundSql) {
        String sql = boundSql.getSql(); // 원본 SQL
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        Object parameterObject = boundSql.getParameterObject();

        // SQL을 포매팅
        String prettySql = SqlFormatter.format(sql);

        StringBuilder modifiedSql = new StringBuilder(prettySql);
        int questionMarkIndex = 0;

        // `?`를 순차적으로 파라미터 이름으로 치환
        for (ParameterMapping parameterMapping : parameterMappings) {
            String paramName = parameterMapping.getProperty();
            Object value = boundSql.getAdditionalParameter(paramName);

            // AdditionalParameter에서 값을 찾지 못하면 parameterObject에서 가져옴
            if (value == null && parameterObject instanceof Map) {
                Map<?, ?> paramMap = (Map<?, ?>) parameterObject;
                value = paramMap.get(paramName);
            }

            // SQL의 `?`를 `:paramName`로 대체
            questionMarkIndex = modifiedSql.indexOf("?", questionMarkIndex);
            if (questionMarkIndex != -1) {
                modifiedSql.replace(
                    questionMarkIndex,
                    questionMarkIndex + 1,
                    ":" + paramName
                );
                questionMarkIndex += paramName.length() + 1; // 위치 이동
            }
        }

        // 결과 반환
        return modifiedSql.toString();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // 필요 시 설정 추가
    }
}

custom interceptor

 import org.apache.ibatis.executor.statement.StatementHandler;

import org.apache.ibatis.plugin.*;

import com.github.vertical_blank.sqlformatter.SqlFormatter;


import java.sql.Connection;

import java.util.Map;

import java.util.Properties;


@Intercepts({

    @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})

})

public class SqlFormattingInterceptor implements Interceptor {


    @Override

    public Object intercept(Invocation invocation) throws Throwable {

        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();

        // 원본 SQL 가져오기

        String originalSql = statementHandler.getBoundSql().getSql();

        Object parameterObject = statementHandler.getBoundSql().getParameterObject();


        // SQL 포매팅 및 파라미터 처리

        String formattedSql = formatSqlWithParameters(originalSql, parameterObject);


        // 로그 출력

        System.out.println("Formatted SQL:");

        System.out.println(formattedSql);


        return invocation.proceed();

    }


    private String formatSqlWithParameters(String sql, Object parameterObject) {

        // SQL을 포매팅

        String prettySql = SqlFormatter.format(sql);


        // 파라미터 정보를 하단에 추가

        StringBuilder parameterComments = new StringBuilder();

        if (parameterObject instanceof Map) {

            Map<String, Object> paramMap = (Map<String, Object>) parameterObject;

            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {

                String paramName = entry.getKey();

                Object value = entry.getValue();

                parameterComments.append("/* :")

                        .append(paramName)

                        .append(" = ")

                        .append(value)

                        .append(" */\n");

            }

        }


        // 포매팅된 SQL과 파라미터 주석 결합

        return prettySql + "\n" + parameterComments.toString();

    }


    @Override

    public Object plugin(Object target) {

        return Plugin.wrap(target, this);

    }


    @Override

    public void setProperties(Properties properties) {

        // 필요에 따라 설정 추가

    }

}



Releases · vertical-blank/sql-formatter