I'm trying to develop a relative simple test on NodeJS 11.6.x. I'm not really a developer, but sometimes try to do some coding.
My objective is to create a SQLite database and repeat some steps every time a run the code: 1. Drop a table if it exists 2. Create a table 3. Insert N lines 4. Count how many lines is in the database 5. Close the database
I tried first with a basic approach using callback, but couldn't figure out a way to make the step 3 (insert N lines) and looking for a solution, the promise async/await 'pattern' sounded the way to accomplish everything.
But, after refactoring the code, the step 1 (drop table) isn't running and I still not being able to execute step 3 (insert N lines) and have no idea what is happening. I also tried to use a promise package with no luck.
Could someone please have a look and help on this and if possible, explain and or give some advice?
Thanks in advance
Edited: Well, I'not used to post here at SO and don't know the 'right' way to update things here. I beleave I should had left the first code as reference, buy I don't have anymore. Now I think I'm almoust there. All steps are executing in order. Just the step 3 (insert N lines) that I'm not able to make it work. Or it inserts and stops not going to the next '.then' or it just insert 1 line and I'm cannot visualize what is happening. In the code, I commented in two lines with 'BUG 1:' and 'BUG 2:'.
- If I both are commented, I get what is happening, it inserts only 1 line and don't continue the promise chain
- If I comment BUG 1 and let BUG 2 active, it inserts just one line and continues. I think I understand why
- If I comment BUG 2 and let BUG 1 active, it inserts all lines but don't continue and again, I think I understand why
- If I uncomment both (the way I think should work. Don't work, and return an aditional error "Segmentation fault"
Bellow the code:
const sqlite3 = require('sqlite3')
let db = new sqlite3.Database('./test.db');
waitTime = 1
process.stdout.write('Starting...\n')
var test = new Promise((resolve, reject) => {
    process.stdout.write('Drop Table... ');
    db.run(`DROP TABLE IF EXISTS test`, (err) => {
        if (err) {
            process.stdout.write(`Dropping Error ${err.message}\n`)
            reject()
        } else {
            setTimeout(() => {
                process.stdout.write(`Dropped!\n`)
                resolve()
            }, waitTime)
        }
    })
})
test.then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Create Table... ')
        db.run(`CREATE TABLE IF NOT EXISTS test (data TEXT)`, (err) => {
            if (err) {
                process.stdout.write(`Creating Error ${err.message}\n`)
                reject()
            } else {
                setTimeout(() => {
                    process.stdout.write(`Created!\n`)
                    resolve()
                }, waitTime)
            }
        })
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Insert Line... ')
        lines = 10
        let loop = (async () => {
            for (let i = 0; i < lines; i++) {
                await new Promise(resolve =>
                    db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
                        if (err) {
                            process.stdout.write(`Inserting Error ${err.message}\n`)
                            throw (err)
                        } else {
                            setTimeout(() => {
                                // process.stdout.write(`Line ${i} Inserted!\n`)
                                process.stdout.write(`, ${i+1}`)
                                resolve() // BUG 1: if this line is commented, comment it, it will insert only 1 line
                            }, waitTime)
                        }
                    })
                )
            }
        })()
        process.stdout.write(`, IDone\n`)
        resolve() // BUG 2: If this line is commented, the promise chain stops here
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Count Line(s)... ')
        db.all(`SELECT COUNT(*) AS totalLines FROM test`, [], (err, rows) => {
            if (err) {
                process.stdout.write(`Count Error ${err.message}\n`)
                reject()
            } else {
                setTimeout(() => {
                    process.stdout.write(` ${rows[0].totalLines} Count!\n`)
                    resolve()
                }, waitTime)
            }
        })
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Select Line(s)... ')
        db.all('SELECT data FROM test', [], (err, rows) => {
            if (err) {
                process.stdout.write(`Select Error ${err.message}\n`)
                reject()
            } else {
                rows.forEach((row) => {
                    console.log(row.data);
                })
                setTimeout(() => {
                    process.stdout.write(`${rows[0].totalLines} Select!\n`)
                    resolve()
                }, waitTime)
            }
        })
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Close DB... ')
        db.close((err) => {
            if (err) {
                process.stdout.write(`Closing Error ${err.message}\n`)
                reject()
            } else {
                setTimeout(() => {
                    process.stdout.write(`Closed!\n`)
                    resolve()
                }, waitTime)
            }
        })
    })
}).then(() => {
    console.log('Finished')
})
After the great explanation from @CertainPerformance (Thanks a lot), I was able to get it running. I believe it is now "the right" way to do it. May be there are some better ways, but for now, it is ok for me, bellow the final code:
const sqlite3 = require('sqlite3')
let db = new sqlite3.Database('./test.db');
lines = 10
process.stdout.write('Starting... ')
var test = new Promise((resolve, reject) => { process.stdout.write(`Promise Created...!\n`)
        resolve()
})
test.then(() => { process.stdout.write('Drop Table... ')
    return new Promise((resolve, reject) => {
        db.run(`DROP TABLE IF EXISTS test`, (err) => {
            if (err) {
                reject(err)
            } else { process.stdout.write(`Dropped!\n`)
                resolve() }
        })
    })
}).then(() => { process.stdout.write('Create Table... ')
    return new Promise((resolve, reject) => {
        db.run(`CREATE TABLE IF NOT EXISTS test (data TEXT)`, (err) => {
            if (err) {
                reject(err)
            } else {
                process.stdout.write(`Created!\n`)
                resolve() }
        })
    })
}).then(() => { process.stdout.write('Insert Line... ')
    let insertLoop = (async () => {
        for (let i = 0; i < lines; i++) {
            await new Promise(resolve =>
                db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
                    if (err) {
                        reject(err)
                    } else { ( i == 0 ) ? process.stdout.write(`${i + 1}`) : process.stdout.write(`, ${i + 1}`)
                        resolve() }
                })
            )
        }
        process.stdout.write(`, Inserted!\n`)
    })()
    return insertLoop
}).then(() => { process.stdout.write('Count Line(s)... ')
    return new Promise((resolve, reject) => {
        db.all(`SELECT COUNT(*) AS totalLines FROM test`, [], (err, rows) => {
            if (err) {
                reject(err)
            } else { process.stdout.write(` ${rows[0].totalLines} Counted!\n`)
                resolve()
            }
        })
    })
}).then(() => { process.stdout.write('Close DB... ')
    return new Promise((resolve, reject) => {
        db.close((err) => {
            if (err) {
                reject(err)
            } else { process.stdout.write(`Closed!\n`)
                resolve()
            }
        })
    })
}).then(() => {
    console.log('Finished')
}).catch((err) => {
    process.stdout.write(`The process did not finish successfully: ${err}`)
})
 
     
    