Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
af9e537
不要なファイルを削除
taichihub Sep 6, 2024
3a6be0e
package管理
taichihub Sep 6, 2024
5cada90
eslint,prettier設定ファイル
taichihub Sep 6, 2024
9fb1338
Eslint,Prettier周り編集
taichihub Sep 6, 2024
615278a
package.json
taichihub Sep 10, 2024
b652d11
データベース関連の処理をするファイル
taichihub Sep 10, 2024
f6c4670
設定ファイルとログファイル
taichihub Sep 10, 2024
f884a7f
コマンドラインメモアプリの内部処理
taichihub Sep 10, 2024
b3e75c7
memo.js(このファイルでメモアプリ全体を動作させる)
taichihub Sep 10, 2024
86921e2
default exportからnamed exportに変更
taichihub Sep 11, 2024
e9a43b2
不必要なファイルを削除
taichihub Oct 4, 2024
36d8dd8
不必要に削除したファイルを復元
taichihub Oct 4, 2024
38245af
inquirerを最新バージョンに更新
taichihub Oct 24, 2024
bfa9e8d
readline-syncパッケージを削除した
taichihub Oct 24, 2024
2175c99
SQL文の不必要な余分/コメントアウトを削除
taichihub Oct 24, 2024
8fc5a52
メモテーブル作成SQL文が格納されている定数名を修正
taichihub Oct 24, 2024
f03ccb4
memo.dbをgit管理下から除外した
taichihub Oct 24, 2024
c403443
クラス名をDatabaseからMemoDatabaseに変更し具体化した
taichihub Oct 24, 2024
f92aa83
他クラスから参照されないメソッドをprivate化
taichihub Oct 24, 2024
93db65b
db取得のメソッドをgetterで再定義
taichihub Oct 24, 2024
89b6bde
DB関連処理をPromiseオブジェクトを用いて修正
taichihub Oct 24, 2024
20665ea
memo.jsの配置場所変更/import文修正
taichihub Oct 24, 2024
f3288c8
インスタンスメソッド名を具体化してわかりやすくした
taichihub Oct 24, 2024
c194940
データベースファイルパスを相対パスから絶対パスにした
taichihub Oct 24, 2024
86fe4a9
handleError関数を解消し、コールバックベースのメソッドに対してPromiseで非同期実装をした
taichihub Oct 25, 2024
f5ce052
ファイル名をappManagerからmemoAppに変更
taichihub Oct 25, 2024
748d963
ファイル名変更によるimport文の修正
taichihub Oct 25, 2024
9aac457
memoApp.jsで行なっていた無駄なカプセル化を解消し、memo.jsに責務を移行した
taichihub Oct 25, 2024
d5e0e7d
Ctrl+C/Dで強制終了した際に同じエラーメッセージが2回表示されてしまう問題を解決
taichihub Oct 25, 2024
f11b24f
memoHelpers.jsをhelpersフォルダの中に移動
taichihub Nov 12, 2024
5690b10
memoAppフォルダが無駄だったのでなくしてディレクトリ構造を修正
taichihub Nov 12, 2024
be2fa74
無駄な空配列の引数を削除
taichihub Nov 12, 2024
2b281ee
memoAppクラスを作成してオブジェクト指向を取り入れた
taichihub Nov 13, 2024
3164ab7
actions配下の処理をmemoApp.jsに統合
taichihub Nov 19, 2024
66e6ef1
ヘルパーファイ修正
taichihub Nov 19, 2024
0ca3b85
dbファイル
taichihub Nov 19, 2024
1ad1a24
メインの実行ファイル編集
taichihub Nov 19, 2024
bfd1058
gitignoreを修正してdbファイルをgit管理から外した
taichihub Nov 26, 2024
5c6bb39
クエリの定数名を全て名詞形にした
taichihub Nov 26, 2024
6d30a0c
不必要なテンプレート文字列を解消
taichihub Nov 26, 2024
874405b
全メモ取得のクエリを最新順で取得するようにした
taichihub Nov 26, 2024
3b820c0
MemoAppがMemoDatabaseのプロパティに依存しない実装にした
taichihub Nov 27, 2024
8051761
無駄なコメントアウトを削除した
taichihub Nov 27, 2024
19192a2
databaseプロパティをプライベートにした
taichihub Nov 27, 2024
b26f70b
content変数をelse文の中で定義した
taichihub Nov 27, 2024
c09c1a7
databaseプロパティをプライベートにした
taichihub Nov 27, 2024
5ce7476
ログファイルにログを追加
taichihub Nov 27, 2024
98b82e4
add/list/read/delete機能ごとにファイル分け
taichihub Nov 27, 2024
da3d426
memoAppクラスの責務が薄くなったので解消
taichihub Nov 27, 2024
8a9f10b
database.jsをmemoDatabase.jsにしてクラス名とファイル名を一致させた
taichihub Nov 27, 2024
1e9207f
ヘルパーファイル修正
taichihub Nov 27, 2024
bb2dfa5
メインのスクリプトファイルとして修正
taichihub Nov 27, 2024
6feccac
定数をクラス内で直接参照する読み込ませ方で無くした
taichihub Dec 10, 2024
b58dd99
コンストラクタで定義する値を修正
taichihub Dec 10, 2024
8417087
connectメソッドの例外処理を修正
taichihub Dec 10, 2024
67f9782
クラス上部をpublicメソッドに、下部をprivateメソッドを定義するようにした
taichihub Dec 10, 2024
a87ed58
テーブル作成SQL文を修正
taichihub Dec 10, 2024
a038466
logMessageとlogErrorを全ファイルから削除してprocessで修正
taichihub Dec 10, 2024
8b7d0dc
不必要なtry...catchを削除
taichihub Dec 10, 2024
8acbaa5
不必要なtry...catch文を削除
taichihub Dec 10, 2024
5806291
selectedMemoIdのチェックを外した
taichihub Dec 10, 2024
9401114
memoの存在のチェックを外した
taichihub Dec 10, 2024
d519f13
memosのundefinedの懸念が無いためundefined対策のチェックを無くした
taichihub Dec 10, 2024
adc2b7d
不必要なtry...catch、変数の値の存在チェックを無くした
taichihub Dec 10, 2024
5389332
TTYと非TTYのメモ追加ロジックを統一させた
taichihub Dec 10, 2024
5a9d3bf
addMemoの処理をPromiseベースで修正した
taichihub Dec 10, 2024
7b8b2bf
配列名を複数形に修正した 
taichihub Dec 10, 2024
ce0a070
checkIfEmptyをensureNotEmptyに命名を修正 
taichihub Dec 10, 2024
82ceffd
プロパティ名と値の変数が同じ場合に省略記法を使用して修正
taichihub Dec 10, 2024
176ed38
addMemoのエラーハンドリングを処理毎に分割した
taichihub Dec 11, 2024
5bac5d6
不必要なtry...catchを削除した
taichihub Dec 11, 2024
740f2ed
return値をつけた
taichihub Dec 11, 2024
cec5c9d
SIGINTイベントの制御を追加
taichihub Dec 11, 2024
2399ee4
表示するメモ・削除するメモ選択の際にCtrl+C/D入力時の挙動修正
taichihub Dec 11, 2024
e988392
メモが存在しない状態でのr・dオプション使用時の挙動修正
taichihub Dec 11, 2024
d9cc68e
NotTTYのメモ追加時のログ表示ロジックを修正
taichihub Dec 12, 2024
e407227
空白判定ロジックを修正
taichihub Dec 12, 2024
11101c5
queriesとlogMessagesのプロパティを削除した
taichihub Dec 18, 2024
e8603c7
カラム名をmemoからcontentに修正
taichihub Dec 18, 2024
547a645
connectメソッドで捕捉するエラーを明確化
taichihub Dec 18, 2024
6e42d3d
#databaseの初期値を無くした
taichihub Dec 18, 2024
7385187
logフォルダを解体して直接ファイルに埋め込み
taichihub Dec 18, 2024
9fbff4a
exitをreturnに置き換え
taichihub Dec 18, 2024
9e78123
exitをreturnにしたことによって処理が進んでしまう箇所のエラーハンドリング
taichihub Dec 18, 2024
3e0fdb7
processと改行文字を使用している箇所でconsoleを使用
taichihub Dec 18, 2024
ecb8ccc
メモ読み込み→出力時に改行をするように
taichihub Dec 18, 2024
d5aaae1
メモ削除時にメモの表示をしないようにした
taichihub Dec 18, 2024
68b2cc3
SIGINT/EOFの入力にはexitを使用するようにした
taichihub Dec 18, 2024
da5a39e
selectMemoでメモ自体を取得するようにして呼び出し側で再検索の処理を要らなくした
taichihub Dec 18, 2024
8578808
selectMemo内でensureNotEmptyの呼び出しを無くした
taichihub Dec 18, 2024
a1939c3
ensureNotEmpty関数を解体した
taichihub Dec 18, 2024
8ec8247
変数名を複数形にして配列が入ることを想起させるようにした
taichihub Dec 18, 2024
f0a4c37
terminalの設定ロジック修正
taichihub Dec 18, 2024
24d614a
メモがない場合のreturn処理を追加
taichihub Dec 18, 2024
a4c3d34
不必要なconsole.logを削除
taichihub Dec 18, 2024
29bc0c8
配列名をlinesに修正
taichihub Dec 18, 2024
7385c44
使用していない設定項目を削除
taichihub Dec 30, 2024
5753e3b
引数をオブジェクトではなく通常の渡し方にした
taichihub Dec 30, 2024
dbda513
エラーメッセージの出力責務とメソッドの責務の範囲を修正
taichihub Dec 30, 2024
5e37171
メソッド名を簡潔に
taichihub Dec 30, 2024
3da8156
import文を参照順に整列
taichihub Dec 30, 2024
04b26b5
returnの実行位置を調整
taichihub Dec 30, 2024
e4725e6
undefinedのパターンを無くした
taichihub Dec 30, 2024
3ba39f7
不必要な引数を削除
taichihub Dec 30, 2024
07372dd
異常終了時は終了ステータス1で終了させるようにした
taichihub Dec 30, 2024
91edcb8
変数名をcontentsからlinesに修正
taichihub Dec 30, 2024
4fb6530
元の変数名とループ処理内の変数の名前を統一
taichihub Dec 30, 2024
75d1487
resolve時に配列そのままを渡すのではなく文字列のみを渡すように修正
taichihub Dec 30, 2024
dfeb341
tryの範囲を狭めて例外が送出されることが想定される箇所を絞った
taichihub Dec 30, 2024
0d103b4
期待するエラーのみを捕捉するようにした
taichihub Dec 30, 2024
385c5a4
メッセージ出力する箇所の責務を修正
taichihub Dec 30, 2024
a7db3b7
tryの範囲を狭めた
taichihub Dec 30, 2024
4dfcc22
エラー捕捉ロジック修正
taichihub Jan 6, 2025
39c7dec
エラー捕捉の範囲を広げた
taichihub Jan 6, 2025
92760af
誤字修正
taichihub Jan 6, 2025
8cb0312
スローする例外のロジックを修正
taichihub Jan 6, 2025
fbcee09
変数の定義位置を修正
taichihub Jan 6, 2025
e5e4ecb
exitではなくreturnで処理終了を対応
taichihub Jan 6, 2025
219798e
closeイベント処理修正
taichihub Jan 6, 2025
e3b23f9
createInterface修正
taichihub Jan 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 04.class/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
db/memo.db
62 changes: 62 additions & 0 deletions 04.class/actions/addMemo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { stdin as input } from "process";
import { createInterface } from "readline";

export async function addMemo(database) {
if (process.stdin.isTTY) {
console.log(
"メモの内容を入力してください(保存するにはCtrl+Dを押してください):",
);
}

let lines;
try {
lines = await getInputLines(input);
} catch (err) {
if (err.message === "SIGINT") {
console.log("Ctrl+Cが入力された為メモの作成を中止しました");
process.exit(1);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exit する処理は memo.js に寄せたほうがよいかと。

}
if (err.code == "ENOMEM") {
throw err;
}
}

const isBlank = /^\s*$/.test(lines);
if (isBlank) {
console.log("メモの内容が空です。");
return;
}

try {
await database.insert(lines);
console.log("メモを追加しました。");
} catch (err) {
console.error(`メモの保存処理中にエラーが発生しました: "${err.message}`);
process.exit(1);
}
}

function getInputLines(input) {
return new Promise((resolve, reject) => {
const rl = createInterface({
input,
});
const lines = [];

rl.on("SIGINT", () => {
reject(new Error("SIGINT"));
});

rl.on("line", (line) => {
lines.push(line);
});

rl.on("close", () => {
resolve(lines.join("\n"));
});

rl.on("error", (err) => {
reject(err);
});
});
}
11 changes: 11 additions & 0 deletions 04.class/actions/deleteMemo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { selectMemo } from "../helpers/memoHelpers.js";

export async function deleteMemo(database) {
const memo = await selectMemo(database, "削除するメモを選んでください:");
if (!memo) {
console.log("メモが存在しません。");
return;
}
await database.delete(memo.id);
console.log("メモを削除しました。");
}
13 changes: 13 additions & 0 deletions 04.class/actions/listMemos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export async function listMemos(database) {
const memos = await database.fetchAll();
if (memos.length === 0) {
console.log("メモが存在しません。");
return;
}

console.log("メモ一覧:");
memos.forEach((memo) => {
const firstLine = memo.content.split("\n")[0];
console.log(`・${firstLine}`);
});
}
10 changes: 10 additions & 0 deletions 04.class/actions/readMemo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { selectMemo } from "../helpers/memoHelpers.js";

export async function readMemo(database) {
const memo = await selectMemo(database, "表示するメモを選んでください:");
if (!memo) {
console.log("メモが存在しません。");
return;
}
console.log(memo.content);
}
6 changes: 6 additions & 0 deletions 04.class/config/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const DATABASE_PATH = "db/memo.db";
export const OPTIONS = {
LIST: "-l",
READ: "-r",
DELETE: "-d",
};
98 changes: 98 additions & 0 deletions 04.class/db/memoDatabase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import sqlite3 from "sqlite3";

export class MemoDatabase {
#database;
#databasePath;

constructor(databasePath = "db/memo.db") {
this.#databasePath = databasePath;
}

async connect() {
try {
this.#database = await this.#openDatabase(this.#databasePath);
} catch (err) {
throw err;
}
Comment on lines +14 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

catch したものを throw するだけならそもそも try...catch で処理する意味がないです。#5 (comment)

}

async createTable() {
try {
await this.#createMemosTable();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

connect() と言いつつ CREATE TABLE まで実行しているのは違和感があります。CREATE TABLE は接続処理ではないからです。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cafedomancer
接続処理とテーブル作成処理でメソッドを別々にしました。

memoDatabase.jsの一部

  async connect() {
    try {
      this.#database = await this.#openDatabase(this.#databasePath);
    } catch (err) {
      if (err.code === "SQLITE_CANTOPEN" || err.code === "SQLITE_NOTADB") {
        throw err;
      }
    }
  }

  async createTable() {
    try {
      await this.#createMemosTable();
    } catch (err) {
      if (err.code === "SQLITE_ERROR") {
        throw err;
      }
    }
  }

memo.jsの一部

  try {
    await memoDatabase.connect();
  } catch (err) {
    switch (err.code) {
      case "SQLITE_CANTOPEN":
        console.error(`データベースを開けません: ${err.message}`);
        break;
      case "SQLITE_NOTADB":
        console.error(`データベースファイルではありません: ${err.message}`);
        break;
    }
    return;
  }

  try {
    await memoDatabase.createTable();
  } catch (err) {
    if (err.code === "SQLITE_ERROR") {
      return console.error(`テーブルを作成できません: ${err.message}`);
    }
  }

} catch (err) {
if (err.code === "SQLITE_ERROR") {
throw err;
}
Comment on lines +23 to +25

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここも修正が必要です。#5 (comment)

}
}

insert(content) {
return new Promise((resolve, reject) => {
this.#database.run(
"INSERT INTO memos (content) VALUES (?)",
[content],
(err) => {
if (err) {
reject(err);
} else {
resolve();
}
},
);
});
}

fetchAll() {
return new Promise((resolve, reject) => {
this.#database.all(
"SELECT * FROM memos ORDER BY id DESC",
(err, rows) => {
if (err) {
reject(err);
} else {
resolve(rows);
}
},
);
});
}

delete(id) {
return new Promise((resolve, reject) => {
this.#database.run("DELETE FROM memos WHERE id = ?", [id], (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}

#openDatabase(path) {
return new Promise((resolve, reject) => {
const db = new sqlite3.Database(path, (err) => {
if (err) {
reject(err);
} else {
resolve(db);
}
});
});
}

#createMemosTable() {
return new Promise((resolve, reject) => {
this.#database.run(
"CREATE TABLE IF NOT EXISTS memos (id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL)",
(err) => {
if (err) {
reject(err);
} else {
resolve();
}
},
);
});
}
}
32 changes: 32 additions & 0 deletions 04.class/helpers/memoHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import inquirer from "inquirer";
import { ExitPromptError } from "@inquirer/core";

export async function selectMemo(database, message) {
const memos = await database.fetchAll();
if (memos.length === 0) {
return null;
}

const choices = memos.map((memo) => ({
name: memo.content.split("\n")[0],
value: memo,
}));

try {
const answer = await inquirer.prompt([
{
type: "list",
name: "selectedMemo",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(現状の実装では) 結果として得られるのは memo ではなく memo の id だと思います。

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cafedomancer
命名が不適切でした🙇‍♂️
#5 (comment) の対応でメモ自体が取得できるようになりましたので、現在のnameで正しくなりました。

message,
choices,
},
]);

return answer.selectedMemo;
} catch (error) {
if (error instanceof ExitPromptError) {
process.stdout.write("Ctrl+C/Dが入力された為処理を終了させました");
process.exit(0);
}
}
}
62 changes: 62 additions & 0 deletions 04.class/memo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env node

import { MemoDatabase } from "./db/memoDatabase.js";
import { DATABASE_PATH, OPTIONS } from "./config/settings.js";
import { listMemos } from "./actions/listMemos.js";
import { readMemo } from "./actions/readMemo.js";
import { deleteMemo } from "./actions/deleteMemo.js";
import { addMemo } from "./actions/addMemo.js";

async function main() {
const memoDatabase = new MemoDatabase(DATABASE_PATH);

try {
await memoDatabase.connect();
} catch (err) {
if (err.code === "SQLITE_CANTOPEN") {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この行で err に対して err.code というプロパティアクセスが行われているので、#5 (comment) にコメントしている問題が解決していないです。

console.error(`データベースを開けません: ${err.message}`);
} else if (err.code === "SQLITE_NOTADB") {
console.error(`データベースファイルではありません: ${err.message}`);
} else {
console.error(`データベースに接続できません: ${err.message}`);
}
process.exit(1);
}

try {
await memoDatabase.createTable();
} catch (err) {
if (err.code === "SQLITE_ERROR") {
console.error(`テーブルを作成できません: ${err.message}`);
} else {
console.error(`エラーが発生しました: ${err.message}`);
}
process.exit(1);
}

const args = process.argv.slice(2);

switch (args[0]) {
case OPTIONS.LIST:
await listMemos(memoDatabase);
break;
case OPTIONS.READ:
await readMemo(memoDatabase);
break;
case OPTIONS.DELETE:
await deleteMemo(memoDatabase);
break;
default:
try {
await addMemo(memoDatabase);
break;
} catch (err) {
if (err.code === "ENOMEM") {
console.error(`システムのメモリ制限を超過しました: ${err.message}`);
process.exit(1);
}
Comment on lines +54 to +57

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここで err.code === "ENOMEM" 以外の場合に異常終了していないのは意図的なものですか?#5 (comment)

}
}
}

main();
Loading