こんにちは、MSKです。
今回はElectronでデータベースを扱ってみます。
最初はNeDBを考えていましたが、「electron-db」というものを見つけたのでこちらを試してみたいと思います。
準備
electron-dbを使うサンプルプロジェクトは下のブログで試したElectron+Next.jsを使っています。
electron-dbのGitHubはここになりますので、詳細を見たい方は飛んでみてください。
まず、インストールを行います。
次のコマンドでインストールができます。
npm install electron-db --save
動かしてみる
テーブルの作成
次のようにTestというテーブルを作成し、サンプルのデータを挿入するtestDbFunctionというメソッドのみを試しに実装してみます。
const db = require('electron-db'); const path = require('path'); interface TEST_DATA{ name: string, date: string, } export const testDbFunction = () => { const savePath:string = path.join("./database",""); if(!db.tableExists('Test',savePath)) { db.createTable('Test',savePath,(success:boolean,msg:string) => { if(success) { console.log(msg); } else { console.log("failed to createTable. "+msg); } }); } else { console.log("already create Test table"); } //テストデータの挿入 const current_date = new Date(); const str_now_time = ('0' + current_date.getHours()).slice(-2) + ":" + ('0' + current_date.getMinutes()).slice(-2); let test_data : TEST_DATA= {name:"MSK",date:str_now_time}; db.insertTableContent('Test',savePath,test_data,(success:boolean,message:string) => { if(success) { console.log("insertTableContent success : "+message); } else { console.log("insertTableContent failed : "+message); } }); //テスト読み込み db.getAll('Test',savePath,(success:boolean,data:[test_object_t])=> { if(success) { console.log("getAll success"); console.log(data); } else { console.log("getAll failed"); } }); };
動作を確認するだけなので、結構ひどいコードではありますが・・・
まず保存するためのTEST_DATAという型を準備しています。
今回は保存する場所を設定したいので、savePathという保存先を指定している変数を準備しています。
次にtableExistsでデータベースが存在するかを確認しています。
存在しなければsavePathに新しくデータベースを作成しています。
次にテストデータを挿入します。
データを挿入した後に全データを取得しています。
以下のファイル名は上で紹介している記事の中で使っているファイルになります。
失敗1
pagesフォルダ以下のindex.tsxファイルを次のように変更しました。
import { useState,useEffect } from 'react' import Router from 'next/router' import Layout from '../components/Layout' import {createDbTable} from "../renderer/lib/database"; const IndexPage = () => { useEffect(()=>{ testDbFunction(); },[]); const clickButton = () => { Router.push("/detail"); } return ( <Layout title="登録ページ"> <h1>登録ページ</h1> <button onClick={clickButton}>Detailページへ</button> </Layout> ) } export default IndexPage
electron-db/index.jsで次のようなエラーが発生します。
error - ../node_modules/electron-db/index.js:3:0 Module not found: Can't resolve 'fs'
いくらか調べてみるとレンダラープロセスで呼び出しているのが問題だということだったので、ipcRendererでメッセージを送って、メインプロセスで動かすようにします。
失敗2
electron-src/index.tsに
const {testDbFunction} = require("./renderer/lib/database");
します。
また、レンダラープロセスからtestDbFunctionを呼び出すメッセージを受信するコードを書きます。
electron_1.ipcMain.on('db-init',() => { testDbFunction(); });
レンダラープロセス側のrenderer/pages/index.tsxを次のように変更して、useEffectでメインプロセスにメッセージを送信します。
import { useState,useEffect } from 'react' import Router from 'next/router' import Layout from '../components/Layout' const IndexPage = () => { useEffect(()=>{ global.ipcRenderer.send('db-init', 'db'); },[]); const clickButton = () => { Router.push("/detail"); } return ( <Layout title="登録ページ"> <h1>登録ページ</h1> <button onClick={clickButton}>Detailページへ</button> </Layout> ) } export default IndexPage
これで実行すると次のエラーが出ました。
成功
エラーを見るとelectron-db/index.jsの処理の中に型エラーが発生しているみたいです。
この中のappNameがstringと確定できないためにエラーになっていると分かりましたので、とりあえず次のように型が文字列であるように指定します。
(この方法がよいかはわかりませんが・・・)
var appName = '' if (pack !== null) { appName = String(pack.name) }
これでエラーがでなくなり、databaseフォルダの中にTest.jsonが出来ていると思います。
また、最後のgetAllでのログにより、挿入したデータも表示されていると思います。
最後に
Typescriptで「electron-db」を動かそうとしたので、少し苦戦してしまいました。
Nedbも使ったことがありますが、こちらも同じくらい使いやすいと感じました。
僕もelectron-dbを使ったアプリを今開発しています。
最後までご覧頂き、ありがとうございます。
「Electronでデータベースを扱ってみる!」でした。