Git: https://github.com/bsorryman/recipe.electron
GitHub - bsorryman/recipe.electron: 레시피 정보를 검색 및 다운로드 할 수 있는 일렉트론 앱.
레시피 정보를 검색 및 다운로드 할 수 있는 일렉트론 앱. Contribute to bsorryman/recipe.electron development by creating an account on GitHub.
github.com
개요
각 레시피에 해당하는 이미지 파일을 image_file 이라는 새로운 BLOB 필드에 삽입할 예정이다. BLOB 필드에 이미지를 삽입하려면 파일을 바이너리화 해야한다.
즉, 모든 이미지 파일을 한번 씩 조회하면서 그에 맞는 레코드의 image_file 필드에 파일을 바이너리화 하여 INSERT 해야한다. 이 로직을 Electron 프로젝트 내에서 구현할 것이다.
- Sqlite DB 연결
- id 1번 레코드의 image_name 필드 조회
- 조회한 image_name의 이미지 파일을 경로에서 찾아 바이너리화
- 바이너리화한 파일을 해당 레코드의 image_file BLOB 필드에 삽입
- 모든 레코드에 이미지를 삽입할 때까지 2-4번을 반복.
DB 경로 확인 및 경로 저장
먼저 Electron 실행 후 DB 접속 전에 올바른 위치에 DB 파일이 있는 지 확인토록 한다. 없으면 앱을 종료시킨다. 또한 올바른 위치에 있다면 후에 DB 접속 및 다른 곳에도 쉽게 경로를 쓸 수 있도록, electron-settings 라이브러리를 사용하여 값을 저장한다.
npm install electron-settings
npm install better-sqlite3
//main.js
const { app, BrowserWindow, dialog} = require('electron');
const path = require('path');
const fs = require('fs');
import RcpSetting from './setting';
.
.
.
mainWindow.once('ready-to-show', () => {
console.log('ready-to-show');
mainWindow.show();
let dbPath;
if (process.env.NODE_ENV == 'production') {
dbPath = path.resolve('D://db/recipe db/recipe.db');
} else {
dbPath = path.resolve('D://db/recipe db/recipe.db');
}
RcpSetting.setDatabasePath(dbPath);
dbPath = RcpSetting.getDatabasePath();
let existDb = fs.existsSync(dbPath);
if (!existDb) {
let timer = setInterval(() => {
dialog.showMessageBox(mainWindow, {type:'error',title:'Error', message:'DB file not found.'})
.then(() => {
mainWindow.close();
});
clearInterval(timer);
}, 500);
}
});
.
.
.
DB 클래스
main.js 에서 DB Instance를 생성해 사용할 수 있도록, DB 관련 클래스를 만든다.
//rcp_sqlite_db.js
import DatabaseConstructor, {Database} from 'better-sqlite3';
import RcpSetting from './setting';
export default class RcpSqliteDB {
db = null;
dbPath = '';
is_open = false;
constructor() {
}
.
.
.
updateImageFileByImageName(imageBuffer, imageName) {
if (this.db == null)
return '';
const stmt = this.db.prepare(
`
UPDATE tb_recipe SET image_file = ?
WHERE image_name = ?
`
);
stmt.run(imageBuffer, imageName);
}
}
클래스 내에 DB 접속 및 쿼리문 실행을 위한 함수를 선언해 놓는다. 이후 DB Instance는 main.js (main process) 에서 하나만 생성해두고 open() 함수를 통해 앱 실행과 동시에 연결을 해둔다.
이미지 바이너리화 및 DB 삽입
//image_binary.js
const path = require('path');
const fs = require('fs');
export default class ImageBinary {
db = null;
constructor(db) {
this.db = db;
}
InsertBinaryToSqliteDB() {
const maxId = this.db.selectMaxId()[0].max_id;
console.log('maxId: ' + maxId);
let id = 0;
while(id <= maxId) {
let imageName = this.db.selectImageNameById(id)[0];
if (imageName === undefined) {
console.log('This is undefined.');
id++;
continue;
}
imageName = imageName.image_name;
let imagePath = path.resolve('D://db/recipe db/Food Images/' + imageName + '.jpg');
let existImage = fs.existsSync(imagePath);
if (existImage) {
let imageBuffer = fs.readFileSync(imagePath);
this.db.updateImageFileByImageName(imageBuffer, imageName);
console.log('update completed: ' + id);
console.log(imageName + 'is completed: ' + imagePath);
} else {
console.log('There is not this image: ' + imageName);
}
id++;
}
}
}
//main.js
.
.
.
import RcpSqliteDB from "../rcp_sqlite_db";
import ImageBinary from "./binary/image_binary";
.
.
.
const createWindow = () => {
.
.
.
mainWindow.once('ready-to-show', () => {
.
.
.
//db open
let db = new RcpSqliteDB();
db.open();
let imageBinary = new ImageBinary(db);
imageBinary.InsertBinaryToSqliteDB();
});
.
.
.
};
ImageBinary 라는 클래스를 만들고 해당 Instance를 main.js (main process)에서 생성한다. ImageBinary의 생성자는 DB Instance를 파라미터로 받는다. 그렇게 생성된 ImageBinary Instance는 내부 함수에서 쿼리문을 실행할 수 있다.
- 가장 큰 id 값을 조회하고 그 수 만큼 반복시킨다.
- 매 반복마다 해당 id로 image_name을 조회하여 이미지 파일 위치를 찾는다.
- 찾은 이미지 파일을 fs.readFileSync(path) 를 통해 버퍼로 변환한다.
- 변환된 binary 데이터는 DB의 BLOB 컬럼에 저장된다.
이제 이후 레시피 이미지를 페이지에서 쓸 일이 있으면, 이미지 파일 없이 DB에서 image_file 컬럼을 조회하고 인코딩하여 사용하면 된다.
'토이 프로젝트 > 레시피 일렉트론 앱 (완)' 카테고리의 다른 글
[Electron] 6.프로세스와 IPC 통신 - 레시피 일렉트론 앱 (1) | 2024.01.23 |
---|---|
[Electron] 5.레시피 압축 파일 생성 및 바이너리화 (0) | 2024.01.22 |
[Electron] 3.Electron 프로젝트 생성 - 레시피 일렉트론 앱 (0) | 2024.01.19 |
[Electron] 2.Sqlite3 DB Fts5 설계 - 레시피 일렉트론 앱 (1) | 2024.01.18 |
[Electron] 1.데이터셋 및 DB 생성 - 레시피 일렉트론 앱 (0) | 2024.01.18 |