SQLite "SELECT" функция-оболочка возвращает пустой объект - PullRequest
0 голосов
/ 09 февраля 2019

Я делаю простое приложение, используя Electron с Node.js и SQLite 3. Моя цель здесь - обернуть базовый запрос SELECT с помощью моей функции.Тем не менее, он не может получить содержимое из базы данных.

Я знаю, что могу выбрать столбец firstname строки следующим образом:

storage.all('select firstname from users where id = 1', [], ( err, rows ) => {
    if ( err ) {
        throw `Error while retrieving ${q}`;
    };
    rows.forEach(( row ) => {
        n.webContents.send( 'userName', row.firstname );
        console.log( 'query output sent: ' + row.firstname );
    });
});

storage здесь мойнастройка базы данных.Вышеприведенное работает хорошо и позволяет мне отправлять мое имя пользователя в мой внешний вид.

Но если я оберну его в функцию, подобную следующей:

let select = ( items, db, where, sign, whereNew ) => {
    // preset sql query
    let q = `select ${items} from ${db}`;
    if ( where && sign && whereNew ) { q += ` where ${where} ${sign} ${whereNew}`};
    let arr;
    console.log(q);

    // perform query on the database
    return storage.each(q, [], ( err, row ) => {
        if ( err ) {
            throw `Error while retrieving ${q}`;
        };
        return row[items];
    });
};

Затем вывод на моей консолибудет пустым Database объектом (см. ниже).

Вот как я вызываю эту функцию и регистрирую ее в консоли:

let u = select( 'firstname', 'users', 'id', '=', 1 );
console.log( 'this log ' + u );

И это вывод консоли:

> szwaczki-react@0.1.0 dev /Users/middleman/Documents/Programowanie/MyApps/szwaczki-react-sqlite
> concurrently "BROWSER=none npm run start" "wait-on http://localhost:3000 && electron ."

[0]
[0] > szwaczki-react@0.1.0 start /Users/middleman/Documents/Programowanie/MyApps/szwaczki-react-sqlite
[0] > react-scripts start
[0]
[0] Starting the development server...
[0]
[1] Connected to the database.sqlite
[0] Compiled with warnings.
[0]
[0] ./src/app.js
[0]   Line 2:  'ReactDOM' is defined but never used  no-unused-vars
[0]
[0] ./src/view/button.js
[0]   Line 2:  'ReactDOM' is defined but never used  no-unused-vars
[0]
[0] Search for the keywords to learn more about each warning.
[0] To ignore, add // eslint-disable-next-line to the line before.
[0]
[1] select firstname from users where id = 1
[1] this log [object Database]
[1] query output sent: Mateusz
^C[0] BROWSER=none npm run start exited with code 0
[1] wait-on http://localhost:3000 && electron . exited with code 0

Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Я думаю, что вроде как ответил на свой вопрос, но у меня все еще есть небольшая проблема с ним.Я следовал асинхронной подсказке, и вот рабочий код:

JS

storage.select = function ( items, db, where, sign, whereNew ) {
    let that = this;
    // preset sql query
    let query = `select ${items} from ${db}`;
    if ( where && sign && whereNew ) { query += ` where ${where} ${sign} ${whereNew}` };

    return new Promise ( function ( resolve, reject ) {
        storage.each( query, [], function ( err, row ) {
            if ( err ) { reject( err )}
            else resolve( row );
        })
    })
};

const result = storage.select( '*', 'users', 'id', '=', 1 )
    .then( row => { l( row ) })
        .catch( err => { l( err ) });

Это прекрасно работает, если я хочу зарегистрировать результат или отправить его в IPC.Renderer,Но я не могу поместить это в переменную или где-либо еще на бэкэнде, что является идеей этой борьбы.

0 голосов
/ 10 февраля 2019

Проблема заключается в том, что функция each возвращает объект Database, который позволяет связывать, а не значение return вашей функции обратного вызова ( согласно документации ).

Чтобы это исправить, и из-за асинхронного поведения SQLite вы можете обернуть функцию API SQLite в Promise, дождаться ее и затем вернуть значение, которое вы хотите получить:

async function select (items, db, where, sign, whereNew) {
    // preset sql query
    let q = `select ${items} from ${db}`;
    if (where && sign && whereNew) {q += ` where ${where} ${sign} ${whereNew}`};

    console.log(q);

    // perform query on the database
    function fetch () {
        return new Promise ((resolve, reject) => {
            storage.each(q, [], ( err, row ) => {
                if (err) {
                    reject (`Error while retrieving ${q}`);
                } else {
                    resolve (row [items]);
                }
            });
        });
    }

    try {
        const result = await fetch ();
        return result;
    } catch (error) {
        throw error;
    }
}

Кстати, это не глупая идея для создания такого SQL-запроса, так как он открыт для SQL-инъекции .Вам следует «подготовить» свои запросы, например, с помощью функции Database#prepare (...) , которая в основном гарантирует, что никакой код SQL, кроме вашего запроса, не может быть выполнен (путем экранирования любых специальных символов, команд и т. Д.).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...