canmove, Confirmed users
2,056
edits
(document the persistent datastore) |
|||
| Line 115: | Line 115: | ||
= Design & Implementation = | = Design & Implementation = | ||
Support for site-specific prefs in Firefox 3 comprises an application-wide service for getting and setting prefs | Support for site-specific prefs in Firefox 3 comprises: | ||
# a persistent datastore for saving prefs across sessions; | |||
# an application-wide service for getting and setting prefs; | |||
# a controller for each browser window that observes pref-related events and notifies handlers about them; | |||
# a handler for the text zoom setting that applies preferences for that setting to the browser and saves changes to that setting as preferences. | |||
== Persistent Datastore == | |||
The persistent datastore is a SQLite database that lives in the profile directory. It gets created automatically if it doesn't exist when the service gets instantiated. It records its schema version in the user_version pragma so that its schema can be updated if modified in the future. | |||
The schema, as declared by a JavaScript data structure in the service's code, is as follows: | |||
_dbSchema: { | |||
groupers: "id INTEGER PRIMARY KEY, \ | |||
name TEXT NOT NULL", | |||
groups: "id INTEGER PRIMARY KEY, \ | |||
name TEXT NOT NULL, \ | |||
grouperID INTEGER NOT NULL REFERENCES groupers(id)", | |||
settings: "id INTEGER PRIMARY KEY, \ | |||
name TEXT NOT NULL", | |||
prefs: "id INTEGER PRIMARY KEY, \ | |||
groupID INTEGER REFERENCES groups(id), \ | |||
settingID INTEGER NOT NULL REFERENCES settings(id), \ | |||
value BLOB" | |||
}, | |||
Some notes: | |||
# The schema (and the code) generally uses the word "setting" to mean "a runtime configuration option that affects the behavior of the application" and the word "pref" or "preference" to mean "a user-defined value for a setting". | |||
# The schema uses arbitrary integers to identify all records, even though all tables have other unique columns (or combinations thereof), primarily because in my experience this approach makes future schema changes easier. Integer IDs may also provide minor space savings and performance improvements. | |||
# The schema tracks groupers (components that categorize URIs by site or via some other mechanism) as a way of namespacing groups created by different groupers. An earlier version of the schema didn't do this, and I'm having second thoughts about it, thinking that we should make groupers be responsible for namespacing their groups in cases where collisions are possible. | |||
# Pref values are stored in a BLOB because it's the only column type that does no type conversion, so it provides maximum round-trip integrity of data from consumers through the service to the datastore and back. | |||
# prefs.groupID is nullable to enable the service to store global preferences (prefs that apply to all groups, a.k.a. the whole web). We could make consumers store global prefs using the existing nsIPrefService, but that'd add significant complexity to consumers, which would have to support two separate and non-compatible interfaces, as nsIPrefService doesn't use nsIVariant. Supporting global prefs in the site-specific pref service, on the other hand, is straightforward and adds relatively little complexity. | |||
== Service == | == Service == | ||