프로그래밍

C# 32비트와 64비트를 모두 지원하는 SQLite 응용 프로그램 개발하기

야라바 2020. 4. 30. 13:42
728x90

NuGet SQLite 32/64bit

다중 사용자 환경이 아닌 응용 프로그램의 데이터베이스로는 SQLite 만한 것이 없다. 윈도, 리눅스, 맥과 같은 범용 운영체제뿐만 아니라 안드로이드 등 수많은 환경에서 SQL 기반으로 프로그래밍을 할 수 있기 때문이다. 파일 시스템을 사용하는 소위 삽질을 하지 않더라도 SQL을 사용해서 가독성도 높이고 생산성과 유지보수 등에 있어 수많은 장점을 가진 프로그램을 개발할 수 있다.

 

SQLite를 사용하는 프로그램은 프로그램 배포 과정에서 문제가 발생할 수 있다. 개발 환경에서는 문제없이 잘 동작했는데 막상 실제 수행 환경으로 가면 종종 문제가 발생하는 것이다. 대부분의 문제를 살펴보면 그 원인은 라이브러리에 있는데 수행 환경의 32비트/64비트 환경과 일치하는 라이브러리가 배포되지 않았기 때문이다. 32비트용과 64비트용을 따로 배포하는 방법도 있겠으나 라이브러리 자체에서 32/64 비트 환경을 자동적으로 인식하여 처리하면 더 간편하게 처리할 수 있다.

 

해당 라이브러리는 비주얼 스튜디오 NuGet 도구를 통해서 프로젝트에 간편하게 포함시킬 수 있는데 도구에서 "SQLite"로 검색하면 상당히 많은 도구들이 검색되는데 그중에서 위의 그림과 같이 System.Data.SQLite.Core(x86/x64)를 선택해서 설치한다.

 

개발에 필요한 라이브러리 파일은 위의 그림과 같으므로 개발 및 배포 환경에 적절히 적용하면 된다. NuGet 도구를 사용하는데 문제가 있는 분들을 위해 아래에 파일을 첨부한다. 라이선스는 Public domain으로 사용 및 배포에 제한이 없다.

 

System.Data.SQLite.Core.1.0.112.2.zip
1.70MB

 

using System;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Data.SQLite;

namespace hisbookcom
{
    public class DBSQLite
    {
        private static String connstr = "Data Source=hisbook.db;Pooling=true;FailIfMissing=false";

        private static SQLiteConnection conn = null;
        public static String error_message = null;

        public static bool open()
        {
            SQLiteCommand cmd;
            if (conn != null) return true;

            try
            {
                conn = new SQLiteConnection(connstr);
                conn.Open();

                //환경 테이블 검사 및 생성, 읽기
                cmd = new SQLiteCommand("SELECT COUNT(*) cnt FROM sqlite_master WHERE name = 'pgmconfig'", conn);
                int chkcnt = Convert.ToInt32(cmd.ExecuteScalar());
                if (chkcnt <= 0) // table not exist -> create 
                {
                    cmd.CommandText = "CREATE TABLE pgmconfig (cfgname VARCHAR(16), cfgint INTEGER, cfgstr VARCHAR(370), PRIMARY KEY(cfgname));";
                    cmd.ExecuteNonQuery();

                    cmd.CommandText = "INSERT INTO pgmconfig (cfgname, cfgint) VALUES ('READ_BOOKLANG', 0);"; 
                    cmd.ExecuteNonQuery();
                }

                cmd.CommandText = "SELECT * FROM pgmconfig";
                DataTable rettbl = getTable(cmd);
                if (rettbl == null || rettbl.Rows.Count <= 0) 
                {
                    conn.Close();
                    error_message += " 환경 읽기 오류";
                    return false;
                }

                foreach (DataRow dr in rettbl.Rows)
                {
                    if (Convert.IsDBNull(dr["cfgint"]))
                        Comgbl.Configstr[dr["cfgname"].ToString()] = dr["cfgstr"].ToString();
                    else
                        Comgbl.Configint[dr["cfgname"].ToString()] = Convert.ToInt32(dr["cfgint"]);
                }
            }
            catch (SQLiteException ex)
            {
                error_message = "DB 초기화 실패 " + ex.Message;
                if (conn != null)
                {
                    conn.Close();
                    conn = null;
                }
                return false;
            }

            return true;
        }

        public static void close()
        {
            if (conn != null) conn.Close();
        }

        public static String escape_str(String instr)
        {
            return instr.Replace("'", "\\'");
        }

        public static DataRow get1Row(SQLiteCommand cmd)
        {
            SQLiteDataReader reader = null;
            DataTable rsttbl = null;

            try
            {
                reader = cmd.ExecuteReader();
                if (!reader.HasRows)
                {
                    reader.Close();
                }
                else
                {
                    rsttbl = new DataTable();
                    rsttbl.Load(reader);
                }
            }
            catch (Exception ex)
            {
                error_message = "DB 오류 " + ex.Message;
            }
            finally
            {
                if (reader != null) reader.Close();
            }
            if (rsttbl != null) return rsttbl.Rows[0];

            return null;
        }

        public static DataTable getTable(SQLiteCommand cmd)
        {
            SQLiteDataReader reader = null;
            DataTable rsttbl = null;

            try
            {
                reader = cmd.ExecuteReader();
                if (!reader.HasRows)
                {
                    reader.Close();
                }
                else
                {
                    rsttbl = new DataTable();
                    rsttbl.Load(reader);
                }
            }
            catch (Exception ex)
            {
                error_message = "DB 오류 " + ex.Message;
            }
            finally
            {
                if (reader != null) reader.Close();
            }
            if (rsttbl != null) return rsttbl;

            return null;
        }
    }
}

 

위의 코드는 DB 연결부터 테이블 존재 여부 검사와 테이블 생성, 데이터 삽입, 쿼리 등을 수행하는 예제이다.

 

 

 

 

728x90