Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9099

ハンズオン Node.jsの7章データストレージ(sqlite3)をTypescriptで試したメモ

$
0
0

概要

前回の続き。
ハンズオン Node.jsの7章データストレージをtypescriptで試す。今回はsqlite。

ソース

環境

package.json
{"name":"node-app","version":"1.0.0","description":"","main":"index.js","scripts":{"start":"node ./bin/www","file-system":"node ./bin/www","sqlite":"node ./bin/www","tsc":"tsc","watch":"tsc --watch"},"keywords":[],"author":"","license":"MIT","engines":{"node":"14.x"},"dependencies":{"express":"^4.17.1","sqlite3":"^5.0.0","uuid":"^8.3.1"},"devDependencies":{"@types/express":"^4.17.9","@types/sqlite3":"^3.1.6","@types/uuid":"^8.3.0","@typescript-eslint/eslint-plugin":"^4.8.2","@typescript-eslint/parser":"^4.8.2","eslint":"^7.14.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.1.4","isomorphic-fetch":"^3.0.0","prettier":"^2.2.0","typescript":"^4.1.2"}}

ソース

  • promisifyしたときの型をtype PromiseDbGet = <T>(arg: string, arg2?: any) => Promise<T>としているが、もうちょっとよい方法ないだろうか
src/fqlite/index.ts
import{promisify}from'util'import{join}from'path'importtype{ID,Todo,DataStorage}from'../types'importtype{RunResult,sqlite3asSqlite3}from'sqlite3'interfaceTodoSQLite{id:IDtitle:stringcompleted:0|1}typeSQLiteArgs=[sql:string,...params:any[]]typePromiseDbGet=<T>(arg:string,arg2?:any)=>Promise<T>typePromiseDbAll=<T>(arg:string,arg2?:any)=>Promise<T>constsqlite3:Sqlite3=process.env.NODE_ENV==='production'?require('sqlite3'):require('sqlite3').verbose()constdb=newsqlite3.Database(join(__dirname,'sqlite'))constdbGet:PromiseDbGet=promisify(db.get.bind(db))constdbRun=function(...args:SQLiteArgs){returnnewPromise<RunResult>((resolve,reject)=>db.run.apply(db,[...args,function(this:RunResult,err:any){err?reject(err):resolve(this)},]),)}constdbAll:PromiseDbAll=promisify(db.all.bind(db))dbRun(`CREATE TABLE IF NOT EXISTS todo (
  id TEXT PRIMARY KEY,
  title TEXT NOT NULL,
  completed BOOLEAN NOT NULL
)`).catch((err)=>{console.log(err)process.exit(1)})functionrowToTodo(row:TodoSQLite):Todo{return{...row,completed:!!row.completed}}constexportsObj:DataStorage<Todo>={fetchAll:()=>dbAll<TodoSQLite[]>('SELECT * FROM todo').then((rows)=>rows.map(rowToTodo),),fetchByCompleted:(completed)=>dbAll<TodoSQLite[]>('SELECT * FROM todo WHERE completed = ?',completed,).then((rows:TodoSQLite[])=>rows.map(rowToTodo)),create:async(todo)=>{awaitdbRun('INSERT INTO todo VALUES (?,?,?)',todo.id,todo.title,todo.completed,)},update:(id,update)=>{constsetColumns=[]constvalues=[]for(constcolumnof['title','completed']asconst){if(columninupdate){setColumns.push(`${column} = ? `)values.push(update[column])}}values.push(id)returndbRun(`UPDATE todo SET ${setColumns.join()} WHERE id = ?`,values,).then(({changes})=>changes===1?dbGet<TodoSQLite>('SELECT * FROM todo WHERE id = ?',id).then(rowToTodo,):null,)},remove:(id)=>dbRun('DELETE FROM todo WHERE id = ?',id).then(({changes})=>changes===1?id:null,),}exportdefaultexportsObj

参考

TypeScriptの型入門
TypeScriptでthisの型を指定する
TypeScriptの型システム


Viewing all articles
Browse latest Browse all 9099

Latest Images

Trending Articles