-
Notifications
You must be signed in to change notification settings - Fork 0
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
非同期処理(JavaScript)のプログラムを作成 #3
Changes from 4 commits
6318887
3081ef8
0a558c9
c5fb47a
952081f
2047128
f1c8683
77123aa
9b90b88
95cd7d9
b7d6d4d
526b0a3
45f478f
edf50f3
ef60c8e
26e8ba8
7f8856a
00979e0
68c7e42
233099e
56986a0
f23f1de
12973cf
6ef5baf
d722ec9
9601d22
a57a47a
8ec4514
92ebeb1
eddc819
4d22ca9
1726f9d
64325e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#!/usr/bin/env node | ||
|
||
import sqlite3 from "sqlite3"; | ||
import { runQueryAsync, allQueryAsync } from "./sqlite_utils.js"; | ||
|
||
sqlite3.verbose(); | ||
const db = new sqlite3.Database(":memory:"); | ||
|
||
const createTableQuery = ` | ||
CREATE TABLE books ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
title TEXT NOT NULL UNIQUE | ||
) | ||
`; | ||
const insertTitleQuery = `INSERT INTO books (title) VALUES (?)`; | ||
const selectAllQuery = `SELECT * FROM movies`; | ||
const deleteTableQuery = `DROP TABLE books`; | ||
|
||
const titles = ["I Am a Cat", "I Am a Cat", "SANSHIRO"]; | ||
|
||
async function main() { | ||
await runQueryAsync(db, createTableQuery); | ||
console.log("Table created"); | ||
|
||
for (const title of titles) { | ||
try { | ||
const result = await runQueryAsync(db, insertTitleQuery, [title]); | ||
console.log(`Record inserted successfully with ID: ${result.lastID}`); | ||
} catch (err) { | ||
console.error(`Error occurred while inserting record: ${err.message}`); | ||
} | ||
} | ||
|
||
try { | ||
const rows = await allQueryAsync(db, selectAllQuery); | ||
console.log("All records fetched successfully"); | ||
for (const row of rows) { | ||
console.log(`id:${row.id}, title:${row.title}`); | ||
} | ||
} catch (err) { | ||
console.error(`Error occurred while fetching records: ${err.message}`); | ||
} | ||
|
||
await runQueryAsync(db, deleteTableQuery); | ||
console.log("Table deleted"); | ||
db.close(); | ||
} | ||
|
||
main(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#!/usr/bin/env node | ||
|
||
import sqlite3 from "sqlite3"; | ||
import { runQueryAsync, allQueryAsync } from "./sqlite_utils.js"; | ||
|
||
sqlite3.verbose(); | ||
const db = new sqlite3.Database(":memory:"); | ||
|
||
const createTableQuery = ` | ||
CREATE TABLE books ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
title TEXT NOT NULL UNIQUE | ||
) | ||
`; | ||
const insertTitleQuery = `INSERT INTO books (title) VALUES (?)`; | ||
const selectAllQuery = `SELECT * FROM books`; | ||
const deleteTableQuery = `DROP TABLE books`; | ||
|
||
const titles = ["I Am a Cat", "KOKORO", "SANSHIRO"]; | ||
|
||
async function main() { | ||
await runQueryAsync(db, createTableQuery); | ||
console.log("Table created"); | ||
|
||
for (const title of titles) { | ||
const result = await runQueryAsync(db, insertTitleQuery, [title]); | ||
console.log(`Record inserted successfully with ID: ${result.lastID}`); | ||
} | ||
|
||
const rows = await allQueryAsync(db, selectAllQuery); | ||
console.log("All records fetched successfully"); | ||
for (const row of rows) { | ||
console.log(`id:${row.id}, title:${row.title}`); | ||
} | ||
|
||
await runQueryAsync(db, deleteTableQuery); | ||
console.log("Table deleted"); | ||
db.close(); | ||
} | ||
|
||
main(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#!/usr/bin/env node | ||
|
||
import sqlite3 from "sqlite3"; | ||
|
||
sqlite3.verbose(); | ||
const db = new sqlite3.Database(":memory:"); | ||
|
||
const createTableQuery = ` | ||
CREATE TABLE books ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
title TEXT NOT NULL UNIQUE | ||
) | ||
`; | ||
const insertTitleQuery = `INSERT INTO books (title) VALUES (?)`; | ||
const selectAllQuery = `SELECT * FROM movies`; | ||
const deleteTableQuery = `DROP TABLE books`; | ||
|
||
const titles = ["I Am a Cat", "I Am a Cat", "SANSHIRO"]; | ||
let insertCount = 0; | ||
|
||
function main() { | ||
createTable(); | ||
} | ||
|
||
function createTable() { | ||
db.run(createTableQuery, insertTitles); | ||
} | ||
|
||
function insertTitles() { | ||
console.log("Table created"); | ||
for (const title of titles) { | ||
db.run(insertTitleQuery, [title], displayID); | ||
} | ||
} | ||
|
||
function displayID(err) { | ||
if (err) { | ||
console.error(`Error occurred while inserting record: ${err.message}`); | ||
} else { | ||
console.log(`Record inserted successfully with ID: ${this.lastID}`); | ||
} | ||
insertCount++; | ||
if (insertCount === titles.length) { | ||
fetchAll(); | ||
} | ||
} | ||
|
||
function fetchAll() { | ||
db.all(selectAllQuery, displayAll); | ||
} | ||
|
||
function displayAll(err, rows) { | ||
if (err) { | ||
console.error(`Error occurred while fetching records: ${err.message}`); | ||
} else { | ||
console.log("All records fetched successfully"); | ||
for (const row of rows) { | ||
console.log(`id:${row.id}, title:${row.title}`); | ||
} | ||
} | ||
deleteTable(); | ||
} | ||
|
||
function deleteTable() { | ||
db.run(deleteTableQuery, closeDB); | ||
} | ||
|
||
function closeDB() { | ||
console.log("Table deleted"); | ||
db.close(); | ||
} | ||
|
||
main(); |
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. noerr ではなく no 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. ファイル名について、noerr を no_error、err を error に修正いたしました。 コミット:952081f |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#!/usr/bin/env node | ||
|
||
import sqlite3 from "sqlite3"; | ||
|
||
sqlite3.verbose(); | ||
const db = new sqlite3.Database(":memory:"); | ||
|
||
const createTableQuery = ` | ||
CREATE TABLE books ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
title TEXT NOT NULL UNIQUE | ||
) | ||
`; | ||
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. 特別長いSQL文ではないため、 |
||
const insertTitleQuery = `INSERT INTO books (title) VALUES (?)`; | ||
const selectAllQuery = `SELECT * FROM books`; | ||
const deleteTableQuery = `DROP TABLE books`; | ||
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. すみません。以前のプラクティスでも同様の指摘をいただいておりました。😭🙏 コミット:2047128 |
||
|
||
const titles = ["I Am a Cat", "KOKORO", "SANSHIRO"]; | ||
let insertCount = 0; | ||
|
||
function main() { | ||
createTable(); | ||
} | ||
|
||
function createTable() { | ||
db.run(createTableQuery, insertTitles); | ||
} | ||
|
||
function insertTitles() { | ||
console.log("Table created"); | ||
for (const title of titles) { | ||
db.run(insertTitleQuery, [title], displayID); | ||
} | ||
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. コールバックベースの非同期処理を for 文で制御することはできませんよ。 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. すみません。 コミット:77123aa 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. ないわけではないです。再起を用いればコールバックベースでも繰り返し処理を実現することはできます。ただし、node-sqlite3 が提供する関数だけでそれを実現することはできません。 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. ご回答ありがとうございます。😌 |
||
} | ||
|
||
function displayID() { | ||
console.log(`Record inserted successfully with ID: ${this.lastID}`); | ||
insertCount++; | ||
if (insertCount === titles.length) { | ||
fetchAll(); | ||
} | ||
} | ||
|
||
function fetchAll() { | ||
db.all(selectAllQuery, displayAll); | ||
} | ||
|
||
function displayAll(err, rows) { | ||
console.log("All records fetched successfully"); | ||
for (const row of rows) { | ||
console.log(`id:${row.id}, title:${row.title}`); | ||
} | ||
deleteTable(); | ||
} | ||
|
||
function deleteTable() { | ||
db.run(deleteTableQuery, closeDB); | ||
} | ||
|
||
function closeDB() { | ||
console.log("Table deleted"); | ||
db.close(); | ||
} | ||
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. 独自の抽象度の関数を削除し、非同期処理をそのまま記述するように修正いたしました。 ひとまず、コールバックベースを修正しております。
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. コミット:7f8856a Promise、async/awaitについて、非同期処理の表現方法が移り変わっていく様子を分かりやすくするため、main関数を削除いたしました。 |
||
|
||
main(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#!/usr/bin/env node | ||
|
||
import sqlite3 from "sqlite3"; | ||
import { runQueryAsync, allQueryAsync } from "./sqlite_utils.js"; | ||
|
||
sqlite3.verbose(); | ||
const db = new sqlite3.Database(":memory:"); | ||
|
||
const createTableQuery = ` | ||
CREATE TABLE books ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
title TEXT NOT NULL UNIQUE | ||
) | ||
`; | ||
const insertTitleQuery = `INSERT INTO books (title) VALUES (?)`; | ||
const selectAllQuery = `SELECT * FROM movies`; | ||
const deleteTableQuery = `DROP TABLE books`; | ||
|
||
const titles = ["I Am a Cat", "I Am a Cat", "SANSHIRO"]; | ||
|
||
function main() { | ||
return runQueryAsync(db, createTableQuery) | ||
.then(function () { | ||
console.log("Table created"); | ||
const requests = titles.map(function (title) { | ||
return runQueryAsync(db, insertTitleQuery, [title]) | ||
.then(function (result) { | ||
console.log( | ||
`Record inserted successfully with ID: ${result.lastID}`, | ||
); | ||
}) | ||
.catch(function (err) { | ||
console.error( | ||
`Error occurred while inserting record: ${err.message}`, | ||
); | ||
}); | ||
}); | ||
return Promise.all(requests); | ||
}) | ||
.then(function () { | ||
return allQueryAsync(db, selectAllQuery); | ||
}) | ||
.then(function (rows) { | ||
console.log("All records fetched successfully"); | ||
for (const row of rows) { | ||
console.log(`id:${row.id}, title:${row.title}`); | ||
} | ||
}) | ||
.catch(function (err) { | ||
console.error(`Error occurred while fetching records: ${err.message}`); | ||
}) | ||
.then(function () { | ||
return runQueryAsync(db, deleteTableQuery); | ||
}) | ||
.then(function () { | ||
console.log("Table deleted"); | ||
}) | ||
.finally(function () { | ||
db.close(); | ||
}); | ||
} | ||
|
||
main(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#!/usr/bin/env node | ||
|
||
import sqlite3 from "sqlite3"; | ||
import { runQueryAsync, allQueryAsync } from "./sqlite_utils.js"; | ||
|
||
sqlite3.verbose(); | ||
const db = new sqlite3.Database(":memory:"); | ||
|
||
const createTableQuery = ` | ||
CREATE TABLE books ( | ||
id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
title TEXT NOT NULL UNIQUE | ||
) | ||
`; | ||
const insertTitleQuery = `INSERT INTO books (title) VALUES (?)`; | ||
const selectAllQuery = `SELECT * FROM books`; | ||
const deleteTableQuery = `DROP TABLE books`; | ||
|
||
const titles = ["I Am a Cat", "KOKORO", "SANSHIRO"]; | ||
|
||
function main() { | ||
return runQueryAsync(db, createTableQuery) | ||
.then(function () { | ||
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. 見づらいので使い分けが必要ない場合は function 式ではなくアロー関数を使ってください。 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. コミット:00979e0 アロー関数を使用するように修正いたしました。 |
||
console.log("Table created"); | ||
const requests = titles.map(function (title) { | ||
return runQueryAsync(db, insertTitleQuery, [title]).then( | ||
function (result) { | ||
console.log( | ||
`Record inserted successfully with ID: ${result.lastID}`, | ||
); | ||
}, | ||
); | ||
}); | ||
return Promise.all(requests); | ||
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. コミット:68c7e42 並列ではなく、直列で実施するように修正いたしました。 |
||
}) | ||
.then(function () { | ||
return allQueryAsync(db, selectAllQuery); | ||
}) | ||
.then(function (rows) { | ||
console.log("All records fetched successfully"); | ||
for (const row of rows) { | ||
console.log(`id:${row.id}, title:${row.title}`); | ||
} | ||
return runQueryAsync(db, deleteTableQuery); | ||
}) | ||
.then(function () { | ||
console.log("Table deleted"); | ||
}) | ||
.finally(function () { | ||
db.close(); | ||
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. close もコールバックベースの非同期処理を行う関数なので Promise として扱えるようにしてください。 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. コミット:233099e close について Promise として扱えるように修正いたしました。 |
||
}); | ||
} | ||
|
||
main(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
export function runQueryAsync(db, query, params = []) { | ||
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. 質問に対する回答がないです。 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. コミット:56986a0 以下の理由のため、[]を削除(省略)いたしました。 |
||
return new Promise(function (resolve, reject) { | ||
db.run(query, params, function (err) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(this); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
export function allQueryAsync(db, query) { | ||
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. 元の all 関数もパラメータを受け付けるはずです。 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. コミット:f23f1de
|
||
return new Promise(function (resolve, reject) { | ||
db.all(query, function (err, rows) { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
resolve(rows); | ||
} | ||
}); | ||
}); | ||
} |
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.
catch では全ての例外が無条件に捕捉されるので、この実装だと例外が握り潰されています。例外は握り潰さずに、捕捉したい例外のみを捕捉するようにしてください。
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.
コミット:12973cf
err.code
の判定処理を追加し、捕捉したい例外のみを捕捉するように修正いたしました。こちらのご指摘は、Promiseにも該当すると思い、Promiseも修正しております。🙏
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.
コミット:eddc819
想定しているエラー(SQLITE_CONSTRAINT、SQLITE_ERROR)以外についても握りつぶさず、捕捉するように修正いたしました。