在 Thunderbird 中查询 SQLite 数据库
Querying SQLite database in Thunderbird
我想为使用 SQLite 数据库的 Thunderbird 制作一个小插件。我用“SQLite Manager”创建了我的数据库。
问题是当我访问数据库时,我得到的消息是它是空的。但事实并非如此!
数据库:
----------------------------
| table1 | table2 | table3 |
----------------------------
| ... | ... | ... |
| ... | ... | ... |
----------------------------
这是 JavaScript 代码。它应该 return 表的名称,但我得到 0.
Components.utils.import("resource://gre/modules/Sqlite.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");
Task.spawn(function() {
let db;
let result;
try {
db = yield Sqlite.openConnection({ path: "db.sqlite" });
result = yield db.execute("SELECT name FROM sqlite_master WHERE type='table'");
alert(result.length);
} catch (ex) {
alert("error: " + ex);
} finally {
if (db) yield db.close();
}
});
谁能告诉我我做错了什么?
是否可以在 Thunderbird 中导入并读取现有的数据库?
谢谢!
查看source code for Sqlite.jsm,路径总是相对于配置文件。但是,您可以访问模块的后台通行证和 copy/paste 来自 openConnection 的代码。这是保存模块中可用的未导出符号的对象。像这样:
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
function openConnection2(path) {
let Sqlite = Components.utils.import("resource://gre/modules/Sqlite.jsm", {});
let file = FileUtils.File(path);
let identifier = Sqlite.getIdentifierByPath(path);
let openedOptions = {};
return new Promise((resolve, reject) => {
let dbOptions = null;
Services.storage.openAsyncDatabase(file, dbOptions, (status, connection) => {
if (!connection) {
reject(new Error(`Could not open connection to ${path}: ${status}`));
return;
}
log.info("Connection opened");
try {
resolve(
new Sqlite.OpenedConnection(connection.QueryInterface(Ci.mozIStorageAsyncConnection),
identifier, openedOptions));
} catch (ex) {
reject(ex);
}
});
});
}
你可以在这里传递你自己的路径,这应该是完整路径。您可以通过将 chrome uri 转换为文件 uri:
来访问您的数据库
let uri = Services.io.newURI("chrome://myext/content/db.sqlite", null, null);
let registry = Cc['@mozilla.org/chrome/chrome-registry;1']
.getService(Ci.nsIChromeRegistry);
let path = registry.convertChromeURL(uri)
.QueryInterface(Ci.nsIFileURL)
.file.path;
yield openConnection2(path); // in your task
请注意,您需要在 install.rdf 中指定 em:unpack
以确保转换后的 uri 实际上是文件 uri 而不是 jar: uri。
我想为使用 SQLite 数据库的 Thunderbird 制作一个小插件。我用“SQLite Manager”创建了我的数据库。 问题是当我访问数据库时,我得到的消息是它是空的。但事实并非如此!
数据库:
----------------------------
| table1 | table2 | table3 |
----------------------------
| ... | ... | ... |
| ... | ... | ... |
----------------------------
这是 JavaScript 代码。它应该 return 表的名称,但我得到 0.
Components.utils.import("resource://gre/modules/Sqlite.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");
Task.spawn(function() {
let db;
let result;
try {
db = yield Sqlite.openConnection({ path: "db.sqlite" });
result = yield db.execute("SELECT name FROM sqlite_master WHERE type='table'");
alert(result.length);
} catch (ex) {
alert("error: " + ex);
} finally {
if (db) yield db.close();
}
});
谁能告诉我我做错了什么?
是否可以在 Thunderbird 中导入并读取现有的数据库?
谢谢!
查看source code for Sqlite.jsm,路径总是相对于配置文件。但是,您可以访问模块的后台通行证和 copy/paste 来自 openConnection 的代码。这是保存模块中可用的未导出符号的对象。像这样:
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
function openConnection2(path) {
let Sqlite = Components.utils.import("resource://gre/modules/Sqlite.jsm", {});
let file = FileUtils.File(path);
let identifier = Sqlite.getIdentifierByPath(path);
let openedOptions = {};
return new Promise((resolve, reject) => {
let dbOptions = null;
Services.storage.openAsyncDatabase(file, dbOptions, (status, connection) => {
if (!connection) {
reject(new Error(`Could not open connection to ${path}: ${status}`));
return;
}
log.info("Connection opened");
try {
resolve(
new Sqlite.OpenedConnection(connection.QueryInterface(Ci.mozIStorageAsyncConnection),
identifier, openedOptions));
} catch (ex) {
reject(ex);
}
});
});
}
你可以在这里传递你自己的路径,这应该是完整路径。您可以通过将 chrome uri 转换为文件 uri:
来访问您的数据库let uri = Services.io.newURI("chrome://myext/content/db.sqlite", null, null);
let registry = Cc['@mozilla.org/chrome/chrome-registry;1']
.getService(Ci.nsIChromeRegistry);
let path = registry.convertChromeURL(uri)
.QueryInterface(Ci.nsIFileURL)
.file.path;
yield openConnection2(path); // in your task
请注意,您需要在 install.rdf 中指定 em:unpack
以确保转换后的 uri 实际上是文件 uri 而不是 jar: uri。