more unifications with xpcshell
[guerillascript.git] / modules / storage.js
blob0ad90d550811ee792b0ea1493fc2a5d46eaf9940
1 /*
2  * Copyright 2004-2007 Aaron Boodman
3  * Portions copyright 2015 Ketmar Dark <ketmar@ketmar.no-ip.org>
4  * Contributors: See contributors list in install.rdf and CREDITS
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * Note that this license applies only to the Greasemonkey extension source
14  * files, not to the user scripts which it runs. User scripts are licensed
15  * separately by their authors.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * The above copyright notice and this permission notice shall be included in all
26  * copies or substantial portions of the Software.
27  */
28 ////////////////////////////////////////////////////////////////////////////////
29 function ScriptStorage (nfo) {
30   this.scriptNfo = nfo;
31   this.dbObj = null;
32   return this;
36 ScriptStorage.prototype.__defineGetter__("dbFile", function () {
37   let file = getUserDBDir();
38   file.append(this.scriptNfo.baseName+".db");
39   return file;
40 });
43 ScriptStorage.prototype.__defineGetter__("db", function () {
44   if (this.dbObj == null) {
45     this.dbObj = Services.storage.openDatabase(this.dbFile);
46     // the auto_vacuum pragma has to be set before the table is created
47     this.dbObj.executeSimpleSQL('PRAGMA auto_vacuum = INCREMENTAL;');
48     this.dbObj.executeSimpleSQL('PRAGMA incremental_vacuum(10);');
49     this.dbObj.executeSimpleSQL('PRAGMA journal_mode = WAL;');
50     this.dbObj.executeSimpleSQL('PRAGMA wal_autocheckpoint = 10;');
51     this.dbObj.executeSimpleSQL(
52       "CREATE TABLE IF NOT EXISTS scriptvals ("+
53       "  name TEXT PRIMARY KEY NOT NULL,"+
54       "  value TEXT"+
55       ")"
56     );
57     // run vacuum once manually to switch to the correct auto_vacuum mode for
58     // databases that were created with incorrect auto_vacuum
59     this.dbObj.executeSimpleSQL('VACUUM;');
60   }
61   return this.dbObj;
62 });
65 ScriptStorage.prototype.__defineGetter__("opened", function () {
66   return (this.dbObj != null);
67 });
70 ScriptStorage.prototype.close = function () {
71   if (this.dbObj) {
72     this.dbObj.close();
73     this.dbObj = null;
74   }
78 ScriptStorage.prototype.setValue = function (name, val) {
79   if (arguments.length != 2) {
80     logError("invalid number of arguments to `GM_setValue()`");
81     throw new Error("invalid number of arguments to `GM_setValue()`");
82   }
83   if (val === null) {
84     this.deleteValue(name);
85     return;
86   }
87   let stmt = this.db.createStatement("INSERT OR REPLACE INTO scriptvals (name, value) VALUES (:name, :value)");
88   try {
89     stmt.params.name = name;
90     stmt.params.value = JSON.stringify(val);
91     stmt.execute();
92   } finally {
93     stmt.reset();
94   }
98 ScriptStorage.prototype.getValue = function (name, defval) {
99   if (arguments.length < 1 || arguments.length > 2) {
100     logError("invalid number of arguments to `GM_getValue()`");
101     throw new Error("invalid number of arguments to `GM_getValue()`");
102   }
103   if (typeof(defval) === "undefined") defval = null;
104   let value = null;
105   let stmt = this.db.createStatement("SELECT value FROM scriptvals WHERE name = :name");
106   try {
107     stmt.params.name = name;
108     while (stmt.step()) value = stmt.row.value;
109   } catch (e) {
110     logException("GM_getValue", e);
111   } finally {
112     stmt.reset();
113   }
114   if (typeof(value) !== "string") return defval;
115   // parse json
116   try {
117     let exposedProps = "__exposedProps__";
118     value = JSON.parse(value);
119     if (typeof(value) == "object") {
120       if (!(exposedProps in value)) value[exposedProps] = {};
121       for (let prop in value) {
122         if (prop !== exposedProps && Object.prototype.hasOwnProperty.call(value, prop)) {
123           value[exposedProps][prop] = "rw"; // there is nothing wrong in making this r/w
124         }
125       }
126     }
127     return value;
128   } catch (e) {
129     //logError("JSON parse error: "+e.name+": "+e.message);
130     return defval;
131   }
135 ScriptStorage.prototype.deleteValue = function (name) {
136   if (arguments.length != 1) {
137     logError("invalid number of arguments to `GM_deleteValue()`");
138     throw new Error("invalid number of arguments to `GM_deleteValue()`");
139   }
140   let stmt = this.db.createStatement("DELETE FROM scriptvals WHERE name = :name");
141   try {
142     stmt.params.name = name;
143     stmt.execute();
144   } finally {
145     stmt.reset();
146   }
150 ScriptStorage.prototype.listValues = function () {
151   if (arguments.length != 0) {
152     logError("invalid number of arguments to `GM_listValues()`");
153     throw new Error("invalid number of arguments to `GM_listValues()`");
154   }
155   let valueNames = [];
156   let stmt = this.db.createStatement("SELECT name FROM scriptvals");
157   try {
158     while (stmt.executeStep()) valueNames.push(stmt.row.name);
159   } finally {
160     stmt.reset();
161   }
162   let vals = Array.prototype.slice.call(valueNames);
163   vals.__exposedProps__ = {'length': 'r'};
164   return vals;
168 ////////////////////////////////////////////////////////////////////////////////
169 exports.ScriptStorage = ScriptStorage;