본문 바로가기
블로그 이미지

방문해 주셔서 감사합니다! 항상 행복하세요!

  
   - 문의사항은 메일 또는 댓글로 언제든 연락주세요.
   - "해줘","답 내놔" 같은 질문은 답변드리지 않습니다.
   - 메일주소 : lts06069@naver.com


Node.js/Electron

일렉트론 시작 - 3 (Electron study, Sqlite와의 연동)

야근없는 행복한 삶을 위해 ~
by 마샤와 곰 2020. 1. 2.

 

어느정도 기초틀이 이루어진 상태에서 sqlite를 활용해서 데이터를 한번 넣어보고 가져오기위한 작업을 진행 하였습니다.

데이터베이스 접속하는 커넥션 함수, 저장함수, 가져오기 함수 등 총 3가지로 나누었고, 해당 기능을 순차적으로 동작 시켜 보았습니다.

main.js에다가 해당 함수를 호출하는 방식으로 사용 하였습니다.

const sqlite3 = require('sqlite3').verbose();

//데이터베이스 관련된 초기 기능
let isConn = false;
let db = new sqlite3.Database('./db/my.db', sqlite3.OPEN_READWRITE, (err) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Connected to the mydb database.');  
    isConn = true;
    db.run('CREATE TABLE IF NOT EXISTS DASH_BOARD ( IDX INTEGER PRIMARY KEY, NAME TEXT, DESC TEXT, DATE TEXT )',[], arg=>{
      console.log('create',arg);
    });
  }
});


//등록하기
module.exports.insert = function(arg){
  if(isConn){
    if(!err){
      db.run('INSERT INTO DASH_BOARD VALUES(?,?,?,?)',[1, '처음', '내용','2020-01-01 00:00:00'], (err,arg)=>{});
    }
  }
};


//가져오기
module.exports.select = function (arg){
  if(isConn){
    db.each('SELECT * FROM DASH_BOARD ',[], (err,arg)=>{
      console.log(arg); 
    });   
  } 
}


돌았다..근데 한글이...???

 

음? 한글이 깨져버렸네요. 인코딩 문제인가 싶어서 구글링을 통해 여러 가지 방법을 적용시켜 보았습니다.

iconv-lite라는 모듈을 설치해 보았습니다.

설치! 결과는???

 

결과는..

엥...안되네???

 

 

utf8이라는 모듈도 있어서 그것도 설치한 뒤에 한번 해 보았습니다.

요렇게 설치해서..

결과는..

뭐야..?ㅠㅠㅠ

 

 

아니..이럴수가..왜 한글이 계속 깨진단 말인가? ㅠㅠ

위 방법 말고도 인코딩과 관련된 여러 기능을 찾아서 해 보았지만 실패 하였습니다.

그러다가 찾은내용이 아래 내용 입니다.

chcp 65001

해당 내용은..CMD에서 한글이 깨질 때 적용시키는 방법 입니다.

즉, 다시말해서..데이터는 정상적으로 잘 저장되고 있었지만 CMD에서의 한글이 지원되지 않아 깨졋 던 것 입니다;;

위 명령어를 cmd에 입력하면 사진처럼 맨 위에 알림이 나타납니다.

한글이제 안깨져요~

 

데이터를 한번 더 넣고 실행하여 보았습니다.

으흑..잘 되는구나..ㅠ

 

한글이 깨진 것 같으면 먼저 cmd에서의 인코딩 형식을 살펴보아야 겠습니다.

sqlite는 기본적으로 utf8을 지원하므로 한글이 안깨진다고 나와 있습니다...ㅠ

 

개발하면서 주의해야 될 점은!

노드js는 기본적으로 데이터베이스와 관련된 행위에 대해서는 거의 대부분 비동기 방식으로 진행 됩니다.

거의 대부분의 스트림(입출력) 행위에 대해서는 콜백행위를 지정하거나 Promise 같은 동기화 처리를 해 주어야 합니다.

내가 결과를 가져가지 않았음에도 불구하고 결과가 끝나버리는 현상이 나타날 수 있습니다.

 

쉽게 말해서..데이터베이스에 접속해서 결과를 가져가기전에 응답끝 현상이 발생 할 수 있습니다.

따라서 위 소스코드에서 select 같은 경우에 데이터를 가져오는 코드로 변경하려면 콜백용 함수나, Promise를 사용하거나 blue버드 같은 외부 모듈을 사용해야 합니다.

여기서는 Promise를 사용하여 수정 하였습니다.

module.exports.select = function (arg){
  return new Promise( (succ, fail)=>{
    if(isConn){
        try {
            if(arg == undefined || arg == null){ //arg는 나중에 조건에서 사용
                arg = [];
            }
            db.all('SELECT * FROM DASH_BOARD ',arg, (err,arg)=>{
                succ(arg); 
            });            
        } catch (error) {
            fail(error);
        }
      } 
  });
}

 

이렇게 수정된 코드를 가져와서 main.js에서는 then을 붙여서 html에 응답해 주도록 바꾸면 됩니다.

ipcMain.on('select', (event, arg) => {
  sripts.select().then( arg=>{
    event.reply('reply', arg);  //결과 완료 후 보내는 방법
  }).catch((error)=>{
    event.reply('reply', error);  //에러
  });
});

 

데이터를 더 넣은뒤의 구동 모습 입니다.

 

최종 적용한 소스코드 입니다.

script.js 내용

const sqlite3 = require('sqlite3').verbose();

let isConn = false;
let db = new sqlite3.Database('./db/my.db', sqlite3.OPEN_READWRITE, (err) => {
    if (err) {
        console.error(err.message);
    } else {
        console.log('Connected to the mydb database.');
        isConn = true;
        db.run('CREATE TABLE IF NOT EXISTS DASH_BOARD ( IDX INTEGER PRIMARY KEY, NAME TEXT, DESC TEXT, DATE TEXT )',[], arg=>{
            console.log('create',arg);
        });
    }
});

module.exports.insert = function(arg){
  if(isConn){
    db.all('SELECT COUNT(*) FROM DASH_BOARD ',[], (err, cnt)=>{  //cnt는 고유 인덱스로 사용하기 위해서 만들었다. 물론 삭제 기능이 들어가면 수정 해야된다.
        if(!err){
            db.run('INSERT INTO DASH_BOARD VALUES(?,?,?,?)',[cnt, arg, arg,'2020-01-01 00:00:00'], (err,arg)=>{});
        }
    }); 
  }
};


module.exports.select = function (arg){
  return new Promise( (succ, fail)=>{  //Promise 사용
    if(isConn){
        try {
            if(arg == undefined || arg == null){
                arg = [];
            }
            db.all('SELECT * FROM DASH_BOARD ',arg, (err,arg)=>{  //일단 조건없이 전부 가져오는 질의문
                succ(arg); 
            });            
        } catch (error) {
            fail(error);
        }
      } 
  });
}

 

main.js 내용

const { app, BrowserWindow } = require('electron');

function createWindow () {  // 브라우저 창을 생성
  let win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true  //require같은 기능 사용 가능하도록
    }
  });
  //브라우저창이 읽어 올 파일 위치
  win.loadFile('./html/index.html');
  //win.setMenu(null); //top 메뉴 세팅
}

app.on('ready', createWindow);


//-------------- html과의 연동 부분 --------------

const sripts = require('./script.js');
const { ipcMain } = require('electron')

ipcMain.on('insert', (event, arg) => {
  sripts.insert(arg);
});

ipcMain.on('select', (event, arg) => {
  sripts.select().then( arg=>{
    event.reply('reply', arg);  //결과 완료 후 보내는 방법
  }).catch((error)=>{
    event.reply('reply', error);  //에러
  });
});

 

index.html 내용

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> hello </title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>

<body>
    <a href='other.html'>next</a>
</body>
</html>
<script>

const { ipcRenderer } = require('electron');
ipcRenderer.send('select', 'param..');  //네이티브js에게 요청한다.

ipcRenderer.on('reply', (event, arg) => {   //네이티브js로부터 받는 녀석
  console.log(arg) 
})

/*
//저장기능
ipcRenderer.send('insert', 'html에서 날라간 한글'); 
*/
</script>

 

만약 require와 관련된 오류가 계속 나온다면 main.js에서 nodeIntegration 관련된 옵션값을  true로 주었는지 확인하여 주세요.

new BrowserWindow(); 로 생성하는 부분에 옵션을 줄 때 nodeIntegration을 줄 수 있습니다.

등록이랑 읽기가 되었으니 다음에는 수정과 삭제까지 기능을 추가해 보아야 겠습니다!

ELECTRON_STUDY.7z
0.03MB

 

* 해당첨부파일에는 node_modules가 없습니다. npm install을 실행하셔서 받으면 테스트 해 볼 수 있습니다.

* 바이러스, 악성코드 절.대.없.습.니.다 ^-^

 

 

반응형
* 위 에니메이션은 Html의 캔버스(canvas)기반으로 동작하는 기능 입니다. Html 캔버스 튜토리얼 도 한번 살펴보세요~ :)
* 직접 만든 Html 캔버스 애니메이션 도 한번 살펴보세요~ :)

댓글