-
Notifications
You must be signed in to change notification settings - Fork 0
20240909 非同期処理(JavaScript) #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 76 commits
896a018
ac18702
ae35975
cb0ab66
18aca3f
c252788
ebd6735
df009bb
cb119d0
e8d6dc1
bb8ad1b
c8ca03b
e91e6c1
a3d569c
f357a12
fd771bb
eebbbe5
2fc8099
ffd1a0b
8953eac
feb7c31
4f3a9f2
184553f
1ed18fc
415cfcb
90a15e8
771d413
5a7a9c4
132f715
b0a51bd
3aec3ec
f576fe0
e66bc94
941c2c5
77b3274
e6b4987
d713856
dc07b1e
6c496ca
e5f5724
638b579
027c90f
b79e014
66d5938
a6ca38b
4d4fbfe
217c638
48ca46d
bfeab6b
7b8d8af
48c3c05
21ae886
1a49633
df85e06
78dc37a
be86392
f3560a7
34623e9
40bd3b8
016ef1b
9a77510
983d77b
1713f95
a1ebfcb
736ca2e
2eb8f3d
1618ed5
bc18241
b0b894e
b73eabe
bb30353
11cfa5a
ce5f300
96bd6ae
703567d
d76d7ea
6845398
d143565
b748124
0495259
41431bb
bb6d305
6fe6e9e
9eb40da
f32f5e5
f248bf9
3c01eed
a740307
f92b465
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#!/usr/bin/env node | ||
|
||
import { createDatabase, run, all, close } from "../db_operations.js"; | ||
|
||
let db = await createDatabase(); | ||
console.log("メモリ内のSQLiteデータベースに接続しました。"); | ||
|
||
try { | ||
await run( | ||
db, | ||
"CREATE TABLE books (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL UNIQUE)", | ||
); | ||
console.log("テーブルが作成されました。"); | ||
|
||
try { | ||
const result = await run(db, "INSERT INTO books (title) VALUES (?)", [ | ||
"Node.js入門", | ||
]); | ||
console.log(`行が追加されました。id: ${result.lastID}`); | ||
await run(db, "INSERT INTO books (title) VALUES (?)", ["Node.js入門"]); | ||
} catch (err) { | ||
if ( | ||
String(err).includes( | ||
"SQLITE_CONSTRAINT: UNIQUE constraint failed: books.title", | ||
) | ||
) { | ||
console.error(`エラーが発生しました: ${String(err)}`); | ||
} else { | ||
throw err; | ||
} | ||
} | ||
|
||
try { | ||
await all(db, "SELECT * FROM nonexistent_table WHERE id = ?", [-1]); | ||
} catch (err) { | ||
console.error(`エラーが発生しました: ${err.message}`); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. この部分は例外が握り潰されてしまっているような。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cafedomancer try {
await all(db, "SELECT * FROM nonexistent_table WHERE id = ?", [-1]);
} catch (err) {
if (
String(err).includes("SQLITE_ERROR: no such table: nonexistent_table")
) {
console.error(`エラーが発生しました: ${err.message}`);
} else {
throw err;
}
} |
||
|
||
await run(db, "DROP TABLE books"); | ||
console.log("テーブルが削除されました。"); | ||
} finally { | ||
await close(db); | ||
console.log("データベース接続を閉じました。"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/usr/bin/env node | ||
|
||
import { createDatabase, run, all, close } from "../db_operations.js"; | ||
|
||
let db = await createDatabase(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. この変数は再代入されないので let で定義する必要はないですね。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cafedomancer const db = await createDatabase(); |
||
console.log("メモリ内のSQLiteデータベースに接続しました。"); | ||
|
||
try { | ||
await run( | ||
db, | ||
"CREATE TABLE books (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL UNIQUE)", | ||
); | ||
console.log("テーブルが作成されました。"); | ||
|
||
const result = await run(db, "INSERT INTO books (title) VALUES (?)", [ | ||
"Node.js入門", | ||
]); | ||
console.log(`行が追加されました。id: ${result.lastID}`); | ||
|
||
const rows = await all(db, "SELECT * FROM books"); | ||
rows.forEach((row) => { | ||
console.log(`${row.id}: ${row.title}`); | ||
}); | ||
|
||
await run(db, "DROP TABLE books"); | ||
console.log("テーブルが削除されました。"); | ||
} finally { | ||
await close(db); | ||
console.log("データベース接続を閉じました。"); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#!/usr/bin/env node | ||
|
||
import sqlite3 from "sqlite3"; | ||
|
||
const db = new sqlite3.Database(":memory:", () => { | ||
console.log("メモリ内のSQLiteデータベースに接続しました。"); | ||
|
||
db.run( | ||
"CREATE TABLE books (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL UNIQUE)", | ||
() => { | ||
console.log("テーブルが作成されました。"); | ||
|
||
db.run( | ||
"INSERT INTO books (title) VALUES (?)", | ||
["Node.js入門"], | ||
function () { | ||
console.log(`行が追加されました。id: ${this.lastID}`); | ||
|
||
db.run( | ||
"INSERT INTO books (title) VALUES (?)", | ||
["Node.js入門"], | ||
(err) => { | ||
if (err) { | ||
console.error(`エラーが発生しました: ${err.message}`); | ||
} | ||
|
||
db.all("SELECT content FROM books", (err) => { | ||
if (err) { | ||
console.error(`エラーが発生しました: ${err.message}`); | ||
} | ||
|
||
db.run("DROP TABLE books", () => { | ||
console.log("テーブルが削除されました。"); | ||
|
||
db.close(() => { | ||
console.log("データベース接続を閉じました。"); | ||
}); | ||
}); | ||
}); | ||
}, | ||
); | ||
}, | ||
); | ||
}, | ||
); | ||
}); |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 見通していたのかもしれませんが、shebang がないのにこのファイルに実行権限が付与されています。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cafedomancer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shebang を付けてもファイルに実行権限が付与されていなければ意味がないですよ。どちらでもいいですが、shebang なし・実行権限なしに統一する、shebang あり、実行権限ありに統一する、のどちらかの対応を行ってください。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cafedomancer
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/usr/bin/env node | ||
|
||
import sqlite3 from "sqlite3"; | ||
|
||
const db = new sqlite3.Database(":memory:", () => { | ||
console.log("メモリ内のSQLiteデータベースに接続しました。"); | ||
|
||
db.run( | ||
"CREATE TABLE books (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL UNIQUE)", | ||
() => { | ||
console.log("テーブルが作成されました。"); | ||
|
||
db.run( | ||
"INSERT INTO books (title) VALUES (?)", | ||
["Node.js入門"], | ||
function () { | ||
console.log(`行が追加されました。id: ${this.lastID}`); | ||
|
||
db.all("SELECT * FROM books", (_, rows) => { | ||
rows.forEach((row) => { | ||
console.log(`${row.id}: ${row.title}`); | ||
}); | ||
|
||
db.run("DROP TABLE books", () => { | ||
console.log("テーブルが削除されました。"); | ||
|
||
db.close(() => { | ||
console.log("データベース接続を閉じました。"); | ||
}); | ||
}); | ||
}); | ||
}, | ||
); | ||
}, | ||
); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import sqlite3 from "sqlite3"; | ||
|
||
export const createDatabase = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 元の There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cafedomancer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cafedomancer createDatabaseexport function createDatabase(filename) {
return new Promise((resolve, reject) => {
const db = new sqlite3.Database(filename, (err) => {
if (err) {
reject(err);
} else {
resolve(db);
}
});
});
} promisecreateDatabase(":memory:")
.then((resolvedDB) => {
..... async/awaitlet db = await createDatabase(":memory:");
..... |
||
return new Promise((resolve, reject) => { | ||
const db = new sqlite3.Database(":memory:", (err) => { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(db); | ||
} | ||
}); | ||
}); | ||
}; | ||
|
||
export function run(db, sql, params) { | ||
return new Promise((resolve, reject) => { | ||
db.run(sql, params, function (err) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. コメントし忘れていましたが、関数はその外部の変数に依存しないようにしてください。再利用性が下がるからです。他に定義したデータベースとこれらの関数を組み合わせて使おうと思っても、現状の実装ではそうできないです。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. db_operations.jsの変更点
export const db = new sqlite3.Database(":memory:");
export const dbReady = new Promise((resolve, reject) => {
db.once("open", () => {
console.log("メモリ内のSQLiteデータベースに接続しました。");
resolve();
});
db.once("error", (err) => reject(err));
}); export function run(db, sql, params) { export function all(db, sql, params) { export function close(db) { promise/.js、async_await/.jsの変更点
promise/*.jsimport { db, dbReady, run, close } from "../db_operations.js";
dbReady
.then(() => {
return run(
db,
"CREATE TABLE books (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL UNIQUE)",
);
})
.......... async_await/*.jsimport { db, dbReady, run, all, close } from "../db_operations.js";
await dbReady;
try {
await run(
db,
"CREATE TABLE books (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL UNIQUE)",
);
.......... |
||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(this); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
export function all(db, sql, params) { | ||
return new Promise((resolve, reject) => { | ||
db.all(sql, params, (err, rows) => { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(rows); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
export function close(db) { | ||
return new Promise((resolve, reject) => { | ||
db.close((err) => { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(); | ||
} | ||
}); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
以下のような文字列を例外として送出すると条件にマッチしてしまうと思いますよ。
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cafedomancer
条件は
SQLITE_CONSTRAINT: UNIQUE constraint failed: books.title
が含まれているかであり、The following error has not occurred: UNIQUE contraint failed
は期待するエラー文と異なるので条件にマッチしないかと思います。実際に上記の例外を創出させてみました。
対象部分のコード
実行結果
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ああ、すみません、文字列に誤りがありましたが、文字列の中身は重要ではないです。以下だとマッチするはずです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cafedomancer
実行結果
記載していただいた文での検証
実行結果
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ちょっと極端ですが、以下のようなコードだと条件にマッチしてしまうと思いますよ。やみくもに条件を増やすのではなく、根本的な対応を考えてください。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cafedomancer
捕捉するエラーに
title
の制約を設けて今回のケース以外にエラーが捕捉されないように修正しました。