we don't really need window observer
[guerillascript.git] / main / modules / sbapi / scriptstorage.js
blobaebc9458b5c3e0a6e0cea65f8d962d7ef18d3d57
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.dbBaseName = nfo.name;
31   this.dbObj = null;
32   return this;
36 ScriptStorage.prototype.__defineGetter__("dbFile", function () {
37   let file = getUserDBDir();
38   file.append(this.dbBaseName+".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 auto_vacuum = NONE;");
50     //this.dbObj.executeSimpleSQL("PRAGMA journal_mode = WAL;");
51     //this.dbObj.executeSimpleSQL("PRAGMA wal_autocheckpoint = 10;");
52     this.dbObj.executeSimpleSQL("PRAGMA journal_mode = DELETE;"); // will slow down bulk inserts, but IDC
53     this.dbObj.executeSimpleSQL(
54       "CREATE TABLE IF NOT EXISTS scriptvals ("+
55       "  name TEXT PRIMARY KEY NOT NULL,"+
56       "  value TEXT"+
57       ")"
58     );
59     // run vacuum once manually to switch to the correct auto_vacuum mode for
60     // databases that were created with incorrect auto_vacuum
61     this.dbObj.executeSimpleSQL("VACUUM;");
62   }
63   return this.dbObj;
64 });
67 ScriptStorage.prototype.__defineGetter__("opened", function () {
68   return (this.dbObj != null);
69 });
72 ScriptStorage.prototype.close = function () {
73   if (this.dbObj) {
74     this.dbObj.close();
75     this.dbObj = null;
76   }
80 ScriptStorage.prototype.setValue = function (name, val) {
81   if (arguments.length != 2) {
82     logError("invalid number of arguments to `GM_setValue()`");
83     throw new Error("invalid number of arguments to `GM_setValue()`");
84   }
85   if (val === null) {
86     this.deleteValue(name);
87     return;
88   }
89   let stmt = this.db.createStatement("INSERT OR REPLACE INTO scriptvals (name, value) VALUES (:name, :value)");
90   try {
91     stmt.params.name = name;
92     stmt.params.value = JSON.stringify(val);
93     stmt.execute();
94   } finally {
95     stmt.reset();
96   }
100 ScriptStorage.prototype.getValue = function (name, defval) {
101   if (arguments.length < 1 || arguments.length > 2) {
102     logError("invalid number of arguments to `GM_getValue()`");
103     throw new Error("invalid number of arguments to `GM_getValue()`");
104   }
105   if (typeof(defval) === "undefined") defval = null;
106   let value = null;
107   let stmt = this.db.createStatement("SELECT value FROM scriptvals WHERE name = :name");
108   try {
109     stmt.params.name = name;
110     while (stmt.step()) value = stmt.row.value;
111   } catch (e) {
112     logException("GM_getValue", e);
113   } finally {
114     stmt.reset();
115   }
116   if (typeof(value) !== "string") return defval;
117   // parse json
118   try {
119     let exposedProps = "__exposedProps__";
120     value = JSON.parse(value);
121     if (typeof(value) == "object") {
122       if (!(exposedProps in value)) value[exposedProps] = {};
123       for (let prop in value) {
124         if (prop !== exposedProps && Object.prototype.hasOwnProperty.call(value, prop)) {
125           value[exposedProps][prop] = "rw"; // there is nothing wrong in making this r/w
126         }
127       }
128     }
129     return value;
130   } catch (e) {
131     //logError("JSON parse error: "+e.name+": "+e.message);
132     return defval;
133   }
137 ScriptStorage.prototype.deleteValue = function (name) {
138   if (arguments.length != 1) {
139     logError("invalid number of arguments to `GM_deleteValue()`");
140     throw new Error("invalid number of arguments to `GM_deleteValue()`");
141   }
142   let stmt = this.db.createStatement("DELETE FROM scriptvals WHERE name = :name");
143   try {
144     stmt.params.name = name;
145     stmt.execute();
146   } finally {
147     stmt.reset();
148   }
152 ScriptStorage.prototype.listValues = function () {
153   if (arguments.length != 0) {
154     logError("invalid number of arguments to `GM_listValues()`");
155     throw new Error("invalid number of arguments to `GM_listValues()`");
156   }
157   let valueNames = [];
158   let stmt = this.db.createStatement("SELECT name FROM scriptvals");
159   try {
160     while (stmt.executeStep()) valueNames.push(stmt.row.name);
161   } finally {
162     stmt.reset();
163   }
164   let vals = Array.prototype.slice.call(valueNames);
165   vals.__exposedProps__ = {length: "r"};
166   return vals;
170 ////////////////////////////////////////////////////////////////////////////////
171 exports.ScriptStorage = ScriptStorage;