Skip to content
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

Cannot SELECT anything out of the DB #706

Closed
ivansopin opened this issue Sep 7, 2016 · 6 comments
Closed

Cannot SELECT anything out of the DB #706

ivansopin opened this issue Sep 7, 2016 · 6 comments

Comments

@ivansopin
Copy link

I am on node.js v4.5.0, and when using node-sqlite3 most operations seem to work fine for me: I can create the database, tables, do inserts, and close the database. However, when I try a SELECT in any fashion (db.all(), db.each(), or db.get()) I get an empty row set back, even though the same query does return proper data in sqlite3 CLI.

Here is the code I'm using:

var sql = "SELECT * FROM " + table.name;
console.log("SQL is " + sql);
db.all(sql, function(err, rows) {
    if (err) {
        console.log(err);
        return;
    }
    console.log("We've got " + rows.length + " rows");
    for (var row in rows) {
        console.log(row);
    }
    console.log("Finished processing");
});

I see "SQL is SELECT * FROM

", "We've got 0 rows" and "Finished processing," but nothing else (indicating there's no error). I have also tried listing SELECT fields individually, using a subset of those, and using aliases, but to no avail.

At this point I am stuck. It seems like an issue in the library, and I see no work-around.

@kroggen
Copy link

kroggen commented Sep 8, 2016

Hi Ivan,

First check the path to the db file. Maybe it is opening another one with an empty table.

@ivansopin
Copy link
Author

The database is removed, if exists, recreated, populated, and read in one session as a series of promise actions. I have made sure that the database a) gets removed; b) gets created; and c) gets populated every time. So, no chance of talking to a different database.

@ivansopin
Copy link
Author

OK, I managed to solve/work around my problem. The issue stemmed from the way I populate the table: Because I am at development stages, I am using a static text file with fake data, and to make the inserts into the DB more efficient, I am running things in transaction mode:

db.run("BEGIN TRANSACTION") -> db.run("INSERT ...")... -> db.run("END")

My callback function was on the last of these calls. Turns out, when that callback got invoked, the data was not yet visible in the subsequent SELECT. Why is that?

The way I reworked this is to wait for the BEGIN call to finish, then for the last of the INSERTs, and finally for the END. This is the sample code with Promises:

function populateTable(table, file) {
    var promise = new Promise(function(resolve, reject) {
        try {
            db.run("BEGIN TRANSACTION", function(err) {
                if (err) {
                    reject(err);
                } else {
                    LineReader.eachLine(file, function(line, last) {
                        if (!last) {
                            db.run("INSERT INTO " + table + " VALUES (" + line + ")", function(err) {
                                if (err) {
                                    reject(err);
                                }
                            });
                        } else {
                            db.run("INSERT INTO " + table + " VALUES (" + line + ")", function(err) {
                                if (err) {
                                    reject(err);
                                } else {
                                    db.run("END", function(err) {
                                        if (err) {
                                            reject(err);
                                        } else {
                                            resolve();
                                        }
                                    });
                                }
                            });
                        }
                    });
                }
            });
        } catch (err) {
            reject(err);
        }
    });

    return promise;
}

Unfortunately, this is pretty elaborate, and I am not even sure that waiting only for the last of the INSERTs is the right thing to do, but this is temporary code for development efforts, so it'll do for the moment. However, before I close this ticket, can you please explain how individual db.run() commands are ordered? Is it reasonable to expect callback from INSERT #1 before INSERT #10?

@kroggen
Copy link

kroggen commented Sep 8, 2016

Use db.serialize

@tmcw
Copy link
Contributor

tmcw commented Sep 22, 2016

Yep, db.serialize should be the solution to this issue, or if you want to use a flow-control library like async or d3-queue. @ivansopin does db.serialize resolve the syntax problem for you?

@ivansopin
Copy link
Author

Yes, it does. Sorry I forgot to close the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants