获取在附加脚本中查询 sqlite db 的结果,以提交到内容脚本

Getting result from querying sqlite db in the add-on script to be submitted to the content script

本文关键字:脚本 结果 提交 db sqlite 查询 获取      更新时间:2023-09-26

我正在编写一个普通的 Firefox 附加组件,我在获取附加脚本的"流程"中使用的结果时遇到了一些问题。

我有代码负责将 sqlite 数据库作为模块进行查询,但我不知道如何在其中创建回调,以便附加脚本中的 pagemod 可以使用它并将其传递给内容脚本。

基本上这是我所拥有的:

  • 主要.js :
var pageMod = require("sdk/page-mod");
var self = require("sdk/self");
var myDbScript = require('./myDbScript');
pageMod.PageMod({
    include: "*.example.com/*",
    contentScriptFile:  [self.data.url('jquery-1.10.2.min.js'),
                        self.data.url('myContentScript.js')],
    onAttach: function(worker) {
        // Query the database on behalf of the content script
        worker.port.on('queryTheDB', function(message) {            
            // Get the data from the DB (é is some test value here)
            // Not working because asynchronous querying of the DB
            var resultFromDB = myDbScript.getResult(2);
            // Send the result to the content script
            worker.port.emit('hereIsYourResult', resultFromDB);
        });
    }
});
  • myDBScript.js
// Get required components
var {components} = require("chrome");
components.utils.import("resource://gre/modules/FileUtils.jsm");
components.utils.import("resource://gre/modules/Services.jsm");
// Some code to get the DB
// Create statement to retrieve country based on the IP
var statement = dbConnection.createStatement("SELECT col1, col2 FROM table WHERE col1 = :given_col1");
function getResult(submittedValue) {    
    // Bind parameters
    statement.params.given_col1 = submittedValue;   
    // Execute
    statement.executeAsync({
        handleResult: function(aResultSet) {
            for (let row = aResultSet.getNextRow();
                 row;
                 row = aResultSet.getNextRow()) {
            var resultFromDB = row.getResultByName("col2");
            }
        },
        handleError: function(aError) {
            print("Error: " + aError.message);
            return 'error';
        },
        handleCompletion: function(aReason) {
            if (aReason != components.interfaces.mozIStorageStatementCallback.REASON_FINISHED) {
                print("Query canceled or aborted!");
                return 'canceledOrAborted';
            } else {
                // Sending the result to the add-on script so that it can
                // pass it to the content script
                notifyingTheAddonScript(resultFromDB);
            }
        }
    });
}
// Enable the use of the getResult function
exports.getResult = getResult;

问题是我不明白如何让插件脚本知道结果已经准备好了。请耐心等待,我是一个菜鸟...

由于我没有完整的源代码,因此无法测试。因此,您必须自己修复我犯的任何错误;)

首先,让我们添加一个回调。

// @param {function(result, error)} callback
// Called upon query completion.
// if |error| is a string, then the query failed.
// Else |result| will contain an array of values. 
function getResult(submittedValue, callback) { // changed   
  // Bind parameters
  statement.params.given_col1 = submittedValue;   
  var rv = [], err = null; // added
  // Execute
  statement.executeAsync({
    handleResult: function(aResultSet) {
      for (let row = aResultSet.getNextRow();
        row;
        row = aResultSet.getNextRow()) {
        rv.push(row.getResultByName("col2")); // changed
      }
    },
    handleError: function(aError) {
      print("Error: " + aError.message);
      err = aError.message; // changed
    },
    handleCompletion: function(aReason) {
      if (aReason != components.interfaces.mozIStorageStatementCallback.REASON_FINISHED) {
        print("Query canceled or aborted!");
        err = err || 'canceled or aborted'; // changed
      }
      callback(err ? null : rv, err); // replaced
    }
  });
}

现在让我们在pagemod中使用这些东西

onAttach: function(worker) {
  // Query the database on behalf of the content script
  worker.port.on('queryTheDB', function(message) {            
    // Get the data from the DB (é is some test value here)
    // Not working because asynchronous querying of the DB
    myDbScript.getResult(2, function callback(result, error) {
      if (error) {
        worker.port.emit("hereIsYourError", error);
        return;
      }
      worker.port.emit("hereIsYourResult", result);
    });
  });
}

您可能需要采取一些预防措施,以免触发多个查询。虽然这样做是可以的,但它可能会损害性能;)

由于我们的回调看起来已经有点像promise,因此使用promises实际上可能是一个好主意,甚至可以使用Sqlite.jsm模块和一些Task.jsm魔法。