def __init__(self, profilePath, binPath, signonsSQLPath=None):
    self.profilePath = profilePath
    self.binPath = binPath

    if not signonsSQLPath:
        signonsSQLPath  = os.path.join(profilePath, "signons.sqlite")

    self.nssSession = NSSSession(self.binPath, self.profilePath)
    self.conn = sqlite3.connect(signonsSQLPath)

    c = self.conn.cursor()
    c.execute("PRAGMA user_version")
    version = c.fetchone()
    c.close()
    if version is None or version[0] == 0:
      self.initSchema()
class SignonsSQLFile(object):
  def __init__(self, profilePath, binPath, signonsSQLPath=None):
    self.profilePath = profilePath
    self.binPath = binPath

    if not signonsSQLPath:
        signonsSQLPath  = os.path.join(profilePath, "signons.sqlite")

    self.nssSession = NSSSession(self.binPath, self.profilePath)
    self.conn = sqlite3.connect(signonsSQLPath)

    c = self.conn.cursor()
    c.execute("PRAGMA user_version")
    version = c.fetchone()
    c.close()
    if version is None or version[0] == 0:
      self.initSchema()

  def close(self):
    self.conn.close()
  def __del__(self):
    self.close()

  def initSchema(self):
    c = self.conn.cursor()
    c.executescript("""
      CREATE TABLE moz_logins (
        id                  INTEGER PRIMARY KEY,
        hostname            TEXT NOT NULL,
        httpRealm           TEXT,
        formSubmitURL       TEXT,
        usernameField       TEXT NOT NULL,
        passwordField       TEXT NOT NULL,
        encryptedUsername   TEXT NOT NULL,
        encryptedPassword   TEXT NOT NULL,
        guid                TEXT,
        encType             INTEGER,
        timeCreated         INTEGER,
        timeLastUsed        INTEGER,
        timePasswordChanged INTEGER,
        timesUsed           INTEGER
      );

      CREATE TABLE moz_disabledHosts (
        id                  INTEGER PRIMARY KEY,
        hostname            TEXT UNIQUE ON CONFLICT REPLACE
      );

      CREATE TABLE moz_deleted_logins (
        id                  INTEGER PRIMARY KEY,
        guid                TEXT,
        timeDeleted         INTEGER
      );

      CREATE INDEX moz_logins_hostname_index ON moz_logins (hostname);
      CREATE INDEX moz_logins_hostname_formSubmitURL_index ON moz_logins (hostname, formSubmitURL);
      CREATE INDEX moz_logins_hostname_httpRealm_index ON moz_logins (hostname, httpRealm);
      CREATE INDEX moz_logins_guid_index ON moz_logins (guid);
      CREATE INDEX moz_logins_encType_index ON moz_logins (encType);

      PRAGMA user_version = 5;
      """)
    self.conn.commit()
    c.close()

  def write(self):
    self.nssSession.stop()
    self.conn.commit()

  def addEntry(self, hostname, httpRealm, user, password):
    now = math.floor(time.time() * 1000)
    params = dict()

    # Explicit args
    params['hostname'] = hostname
    params['httpRealm'] = httpRealm
    params['encryptedUsername'] = self.nssSession.encrypt(user)
    params['encryptedPassword'] = self.nssSession.encrypt(password)

    # automatic args
    params['formSubmitURL'] = ''
    params['usernameField'] = ''
    params['passwordField'] = ''
    params['guid'] = "{%s}" % str(uuid.uuid4())
    params['encType'] = 1
    params['timeCreated'] = now
    params['timeLastUsed'] = now
    params['timePasswordChanged'] = now
    params['timesUsed'] = 1

    c = self.conn.cursor()
    if self.conn.execute("""SELECT 1 FROM moz_logins
                             WHERE (hostname=:hostname AND httpRealm=:httpRealm)
                             """, params).fetchone() is None:
        c.execute("""INSERT INTO moz_logins
                       (hostname, httpRealm, formSubmitURL, usernameField,
                        passwordField, encryptedUsername, encryptedPassword, guid,
                        encType, timeCreated, timeLastUsed, timePasswordChanged,
                        timesUsed)
                      VALUES (:hostname, :httpRealm, :formSubmitURL,
                              :usernameField, :passwordField, :encryptedUsername,
                              :encryptedPassword, :guid, :encType, :timeCreated,
                              :timeLastUsed, :timePasswordChanged, :timesUsed)
                   """, params)
    else:
        c.execute("""UPDATE moz_logins
                        SET guid=:guid, encType=:encType,
                            encryptedUsername=:encryptedUsername,
                            encryptedPassword=:encryptedPassword,
                            timeCreated=:timeCreated,
                            timeLastUsed=:timeLastUsed,
                            timePasswordChanged=:timePasswordChanged,
                            timesUsed=:timesUsed
                   """, params)
    self.conn.commit()
    c.close()