2015-12-10 2 views
1

Я ищу информацию о том, как наилучшим образом написать этот фрагмент кода.Получение ошибок BUSY с использованием nodejs и sqlite

Я хочу, чтобы все эти команды запускались синхронно, поэтому я пытаюсь использовать функцию db.serialize.

мне нужно сделать некоторые другие вещи БД на основе результатов запроса (BTW я еще узел новичок)

я впервые попробовал этот

var db = new sqlite3.Database(file); 
var stmt = "SELECT image_id FROM image WHERE file_downloaded = 1 ORDER BY image_id DESC LIMIT 1"; 
db.serialize(function() { 
    db.all(stmt, function(err, rows) { 
     if (err){ 
      if (err) { logger.error('Error %j', err); throw err; } 
     } 
     if (rows.length > 0){ 
       db.run("DELETE FROM image_status"); 
       db.run("INSERT INTO image_status (next_new_id, next_type , restart_new ) VALUES ("+rows[0].image_id+",'old',"+restart_new+")"); 
       db.run("UPDATE image_status SET next_old_id = (SELECT image_id FROM image WHERE file_downloaded = 1 ORDER BY image_id ASC LIMIT 1)"); 
       db.all("SELECT next_old_id FROM image_status LIMIT 1", function(err, rows) { 
        if (err) { logger.error('connection %j', err); throw err; } 
        if (rows.length > 0){ 
         next_old_id = rows[0].next_old_id; 
        } 
        mycallback(next_new_id, next_old_id,'old'); 
       }) 
     } 
    }) 
}); 
db.close(); 

Но, конечно, к тому времени я добрался до части DELETE, db уже закрыт Итак, я попробовал, где я переместил db.serialize внутри обратного вызова для запроса, а затем управлял закрытием DB в обратном вызове. Это, похоже, не лучшее решение (я получаю, что случайный DB занят другими событиями). Я ищу правильный способ сделать это.

Спасибо за любую помощь

var db = new sqlite3.Database(file); 
var stmt = "SELECT image_id FROM image WHERE file_downloaded = 1 ORDER BY image_id DESC LIMIT 1"; 
db.all(stmt, function(err, rows) { 
    if (err){ 
     db.close(); 
     if (err) { logger.error('Error %j', err); throw err; } 
    } 
    if (rows.length > 0){ 
     db.serialize(function() { 
      db.run("DELETE FROM image_status"); 
      db.run("INSERT INTO image_status (next_new_id, next_type , restart_new ) VALUES ("+rows[0].image_id+",'old',"+restart_new+")"); 
      db.run("UPDATE image_status SET next_old_id = (SELECT image_id FROM image WHERE file_downloaded = 1 ORDER BY image_id ASC LIMIT 1)"); 
      db.all("SELECT next_old_id FROM image_status LIMIT 1", function(err, rows) { 
       if (err) { logger.error('connection %j', err); throw err; } 
       if (rows.length > 0){ 
        next_old_id = rows[0].next_old_id; 
       } 
       mycallback(next_new_id, next_old_id,'old'); 
      }) 
      db.close(); 
     }); 
    }else{ 
     db.close(); 
    } 
}) 

ответ

1

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

В обещаниях Bluebird есть опция .finally, где вы можете поместить db.close(), и она будет работать после выполнения всех ваших обещаний вызова db.

0

реорганизован ниже. Другая часть, которая вызывала у меня проблемы, была db.all. После того, как я реорганизовал, db.all не видел вставку. Замена db.each фиксированной этой части:

db.serialize(function() { 
    db.run("DELETE FROM image_status"); 
    var stmt = db.prepare("INSERT INTO image_status (restart_new , next_type , next_new_id, next_old_id) " 
          +"VALUES (?,'old'," + 
          "(SELECT image_id FROM image WHERE file_downloaded = 1 ORDER BY image_id DESC LIMIT 1)," + 
          "(SELECT image_id FROM image WHERE file_downloaded = 1 ORDER BY image_id ASC LIMIT 1))" 
         ); 
    stmt.run(restart_new); 
    stmt.finalize(); 

    db.each("SELECT next_new_id, next_old_id FROM image_status LIMIT 1", function(err, row) { 
     if (err) { logger.error('connection %j', err); throw err; } 
     mycallback(row.next_new_id, row.next_old_id,'old'); 
    }); 
}); 
db.close(); 
Смежные вопросы