반응형

최근 압축 및 압축해제를 구현해야해서 라이브러리를 찾아보던 중

IONIC.ZIP 라이브러리를 사용하게 되었습니다.

 

설치는 비주얼스튜디오 NuGet에서 Ionic으로 검색하면 설치할 수 있습니다.

 

예제는 선택한 폴더를 압축/압축해제 하는 예제 코드 입니다.

 

1. 압축

        private void zipFolder()
        {
            string sSourcePath = tbLoadFolderPath.Text;
            string sTargetPath = tbSavePath.Text;

            try
            {
                using (ZipFile zip = new ZipFile())
                {
                    DirectoryInfo di = new DirectoryInfo(sSourcePath);
                    //프로그레스바 최대 값 (디렉토리내 모든 파일 수)
                    mMaximum += di.GetFiles("*.*", System.IO.SearchOption.AllDirectories).Count();

                    //프로그레스바 이벤트 설정
                    zip.SaveProgress += Zip_SaveProgress;


                    FileInfo[] infos = di.GetFiles("*.*", SearchOption.AllDirectories);

                    string[] files = new string[infos.Length];

                    for (int i = 0; i < infos.Length; i++)
                    {
                        files[i] = infos[i].FullName;
                    }

                    byte[] b = null;
                    string fileName = string.Empty;

                    foreach (string file in files)
                    {
                        fileName = file.Replace(sSourcePath, "");

                        //기본 인코딩 타입으로 읽기
                        b = Encoding.Default.GetBytes(fileName);

                        // IBM437로 변환
                        fileName = Encoding.GetEncoding("IBM437").GetString(b);

                        zip.AddEntry(fileName, File.ReadAllBytes(file));
                    }

                    DirectoryInfo dir = new DirectoryInfo(sTargetPath);

                    if(!dir.Exists)
                    {
                        dir.Create();
                    }

                    string[] split = sSourcePath.Split('\\');

                    string sZipName = split[split.Length - 1];

                    zip.Save($"{sTargetPath}\\{sZipName}.zip");
                }
                Process.Start(sTargetPath);
            }
            catch(Exception ex)
            {
                MessageBox.Show($"{ex.Message}\r\n압축 실패");
                return;
            }
        }

 

2. 압축 해제

 

       private void unZipFile()
        {
            string sSourcePath = tbLoadZipPath.Text;
            string sTargetPath = tbSavePath.Text;

            try
            {
                using (ZipFile zip = ZipFile.Read(sSourcePath))
                {
                    FileInfo fi = new FileInfo(sSourcePath);

                    zip.ExtractProgress += Extract_Progress;

                    //프로그레스바 맥시멈 값
                    mMaximum = zip.Entries.Count;

                    DirectoryInfo dir = new DirectoryInfo(sTargetPath);

                    if (!dir.Exists)
                    {
                        dir.Create();
                    }

                    string saveFolderPath = $"{sTargetPath}\\{Path.GetFileNameWithoutExtension(sSourcePath)}";

                    for (int i = 0; i < zip.Entries.Count; i++)
                    {
                        ZipEntry entry = zip[i];

                        //IBM437 인코딩
                        byte[] byteIbm437 = Encoding.GetEncoding("IBM437").GetBytes(zip[i].FileName);
                        //euckr 인코딩
                        string euckrFileName = Encoding.GetEncoding("euc-kr").GetString(byteIbm437);

                        zip[i].FileName = euckrFileName;

                        entry.Extract(saveFolderPath, ExtractExistingFileAction.OverwriteSilently);
                    }
                    Process.Start(saveFolderPath);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"{ex.Message}\r\n압축 해제 실패");
                return;
            }
        }

 

 

3. 예제 소스 코드 파일

 

 

 

 

 

 

 

 

 

 

 

 

WindowsFormsApp3.zip
0.86MB

프로그레스바를 ionic.zip에서 지원하는 이벤트로만 구현했는데

개인적으로 사용하실때에는 조금 손보는게 좋을 것 같습니다.

 

예제 코드는 이전에 구글링한 자료에 집에서 생각나는것만 정리한 정도이니 참고만 하시면 될 것 같습니다

 

 

 

반응형
반응형

SQL SERVER AFTER 트리거 사용 시

특정 컬럼 업데이트를 감지하여 작동하는 쿼리 예제 입니다.

 

흔히 이력 정보를 저장할 때, 특정 컬럼의 값이 변하는지 감지하고

감지하는 컬럼의 값이 변할때만 작동하도록 해야하는 상황이 많습니다.

 

예제.

사용자 테이블과 사용자 이력 테이블 트리거 작성

 

트리거를 가지고 있는 USERS 테이블 

*[USER_ID], [USER_NM], [USER_PWD], [USER_ST], [EDT_DT]

 

USERS 테이블의 이력을 저장할 USERS_HIS 테이블

*[USER_ID], *[HIS_IDX], [USER_NM], [USER_ST], [EDT_DT]

 

목표는 USERS 테이블의 [USER_ST] (유저 상태)컬럼 값이 변할 때 이력을 저장하는 것 입니다.

[USER_ST]가 변할 때 USERS_HIS 테이블에 데이터를 삽입하도록 트리거를 작성하면 됩니다.

 

예제는 다음과 같습니다.

 

 

 

 

트리거 INSERTED 와 DELTED 시에는 그냥 이력을 삽입하면되니 UPDATED만 예제로 작성하겠습니다.

 

1. 트리거 쿼리문

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		davi
-- Create date: 210323
-- Description:	Insert history when [USERS]'s USER_ST updated
-- =============================================
CREATE TRIGGER [dbo].[TRG_USERS_UPDATED]
   ON  [dbo].[USERS]
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.

	SET NOCOUNT ON;
    --USER 테이블에서 이력을 저장할 컬럼 변수 생성
	DECLARE
	@USER_ID varchar(20),
	@HIS_IDX int,
	@USER_NM varchar(10),
	@USER_ST	char(1),
	@EDT_DT datetime

		--I : INSERTED
		--U : UPDATED
		--D : DELETED
		DECLARE @TRG_ACTION char(1)

		--INSERTED
		SET @TRG_ACTION = 'I'

		--U : UPDATED
		--D : DELETED
		IF EXISTS(SELECT * FROM deleted)
		  BEGIN
		    SET @TRG_ACTION = (CASE WHEN EXISTS (SELECT * FROM inserted) THEN 'U' ELSE 'D' END)
		  END


		  --UPDATED 만 작성
		  IF @TRG_ACTION = 'U'
		   BEGIN
			SELECT 
			  @USER_ID = INS.USER_ID, @USER_NM = INS.USER_NM, @USER_ST = INS.USER_ST, @EDT_DT = INS.EDT_DT
			FROM DELETED DEL
			JOIN INSERTED INS ON DEL.USER_ID = INS.USER_ID --PK로 JOIN
			WHERE 
			DEL.USER_ID = INS.USER_ID AND
			DEL.USER_ST != INS.USER_ST --컬럼 값이 다르면 USER_ST가 변경되었을때이다.  
		   END

		   IF(@USER_ID IS NOT NULL)
		     BEGIN
			   --USERS_HIS 테이블에서 해당 USER_ID의 변경 순서 +1
			   SELECT @HIS_IDX = ISNULL(MAX(HIS_IDX),0)+1 FROM USERS_HIS WITH(NOLOCK) WHERE USER_ID = @USER_ID

			   --USERS_HIS 삽입
			   INSERT INTO USERS_HIS 
			   (USER_ID, HIS_IDX, USER_NM, USER_ST, EDT_DT) VALUES
			   (@USER_ID, @HIS_IDX, @USER_NM, @USER_ST, @EDT_DT)
			 END

END
GO

 

해당 쿼리는 업데이트 후 정보를 이력으로 저장 했습니다.

 

 

 

2. 트리거 검증 

 

 1) 검증 쿼리

--변경전
SELECT * FROM USERS

SELECT * FROM USERS_HIS

--USER_ST 및 다른 값 업데이트
UPDATE USERS
  SET USER_ST = 2, USER_NM = '이지은', EDT_DT = GETDATE()
WHERE USER_ID = 'davi'

-- USER_ST 업데이트 후
SELECT * FROM USERS

SELECT * FROM USERS_HIS

 

 2) 결과

 

 

간단하게 작성하려고 했는데 은근히 시간이 오래 걸리네요.

 

참고 하시고 오류 있으면 댓글 부탁드립니다.

반응형
반응형

 

오버맥스 그립 후기

 

유명한 오버맥스 그립을 구매해봤습니다.

 

당기는 운동을 할때 손목에 부담을 줄여주고

  

여러 각도로 등에 자극을 줄 수 있다고 합니다.

 

실제로 바디빌더 분들도 많이 사용하시더라구요

 

마침 구매할때 크리스마스 시즌이라

 

한정판 컬러로 구매해봤습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

운동 후기 - 풀업

 

 

등운동은 주로 풀업, 랫풀다운, 바벨로우를 즐겨하는데

 

세 운동에 모두 오버맥스 그립을 이용하여 운동해봤습니다.

 

홈짐이다 보니 그립을 연결하면 풀업시 무릎을 접어야하는데

 

무릎을 접은게 문제인지 그립이 안맞는지

 

개인적으로 조금 불편한감이 있었습니다

 

그래도 풀업시에 가끔 색다른 자극을 위해 사용하고 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

운동후기 - 랫풀다운, 바벨로우

 

 

랫풀다운은 일자바에 연결하여

 

와이드, 내로우 여러가지 각도를 사용해서 사용해봤습니다.

 

랫풀다운시에 확실히 자극이 좋은 것 같습니다. 

 

바벨로우는 가끔 손목에 불편한감이 있었는데

 

오버맥스그립을 사용하니 확실히 손목이 편한 것 같습니다. 

 

무엇보다 홈짐에 포인트 인테리어로 아주 좋네요..

 

역시 홈짐은 인테리어라는걸 한번 더 느낍니다.

 

반응형

+ Recent posts