Use SQLite

If you'd like to use an SQLite database in your extension you'll need to look over the Storage docs for an API reference, however this code should get you started. Be careful of multi-thread access to your database.

This will create an SQLite db named tbird.sqlite inside your profile directory with a table called attachments. You can see the schema for the attachments table in the code. To double check the information you've inserted you can query the tbird.sqlite file using regular SQLite programs.

const Cc = Components.classes;
const Ci = Components.interfaces;

var tbirdsqlite = {

  onLoad: function() {
    // initialization code
    this.initialized = true;
    this.dbInit();
  },

  dbConnection: null,

  dbSchema: {
     tables: {
       attachments:"id           INTEGER PRIMARY KEY, \
                    name         TEXT \
                    encoded      TEXT NOT NULL"
    }
  },

  dbInit: function() {
    var dirService = Cc["@mozilla.org/file/directory_service;1"].
      getService(Ci.nsIProperties);

    var dbFile = dirService.get("ProfD", Ci.nsIFile);
    dbFile.append("tbird.sqlite");

    var dbService = Cc["@mozilla.org/storage/service;1"].
      getService(Ci.mozIStorageService);

    var dbConnection;

    if (!dbFile.exists())
      dbConnection = this._dbCreate(dbService, dbFile);
    else {
      dbConnection = dbService.openDatabase(dbFile);
    }
    this.dbConnection = dbConnection;
  },

  _dbCreate: function(aDBService, aDBFile) {
    var dbConnection = aDBService.openDatabase(aDBFile);
    this._dbCreateTables(dbConnection);
    return dbConnection;
  },

  _dbCreateTables: function(aDBConnection) {
    for(var name in this.dbSchema.tables)
      aDBConnection.createTable(name, this.dbSchema.tables[name]);
  },
};
window.addEventListener("load", function(e) { tbirdsqlite.onLoad(e); }, false);

This is another practical sample on how to handle openDatabase and SQL queries on the Client Side, using in-memory (BLOB) storage of 2Mb:

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
var msg;
db.transaction(function (tx) {
  tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
  tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "foobar")');
  tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "logmsg")');
  msg = '<p>Log message created and row inserted.</p>';
  document.querySelector('#status').innerHTML =  msg;
});

db.transaction(function (tx) {
  tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
   var len = results.rows.length, i;
   msg = "<p>Found rows: " + len + "</p>";
   document.querySelector('#status').innerHTML +=  msg;
   for (i = 0; i < len; i++){
     msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
     document.querySelector('#status').innerHTML +=  msg;
   }
 }, null);
});