• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 function terminateTest()
2 {
3     if (window.layoutTestController)
4         layoutTestController.notifyDone();
5 }
6 
7 function logAndTerminateTest(message, error)
8 {
9     log(message + ": " + error.message);
10     terminateTest();
11 }
12 
13 function cleanup(db)
14 {
15     db.transaction(function(tx) {
16             tx.executeSql("DROP TABLE IF EXISTS Test;");
17             tx.executeSql("DROP INDEX IF EXISTS TestIndex;");
18             tx.executeSql("DROP VIEW IF EXISTS TestView;");
19             tx.executeSql("DROP TRIGGER IF EXISTS TestTrigger;");
20         }, function(error) { logAndTerminateTest("Cleanup failed", error); });
21 }
22 
23 function statementSuccessCallback(statementType)
24 {
25     log(statementType + " statement succeeded.");
26 }
27 
28 function statementErrorCallback(statementType, error)
29 {
30     log(statementType + " statement failed: " + error.message);
31     return false;
32 }
33 
34 function executeStatement(tx, statement, operation)
35 {
36     tx.executeSql(statement, [],
37                   function(result) { statementSuccessCallback(operation); },
38                   function(tx, error) { return statementErrorCallback(operation, error); });
39 }
40 
41 function createTableCallback(tx)
42 {
43     executeStatement(tx, "CREATE TABLE Test (Foo int);", "SQLITE_CREATE_TABLE");
44 }
45 
46 function createStatementsCallback(tx)
47 {
48     executeStatement(tx, "CREATE INDEX TestIndex ON Test (Foo);", "SQLITE_CREATE_INDEX");
49 
50     // Even though the following query should trigger a SQLITE_CREATE_TEMP_INDEX operation
51     // (according to http://www.sqlite.org/tempfiles.html), it doesn't, and I'm not aware
52     // of any other way to trigger this operation. So we'll skip it for now.
53     //executeStatement(tx, "SELECT * FROM Test WHERE Foo IN (1, 2, 3);", "SQLITE_CREATE_TEMP_INDEX");
54 
55     executeStatement(tx, "CREATE TEMP TABLE TestTempTable (Foo int);", "SQLITE_CREATE_TEMP_TABLE");
56     executeStatement(tx, "CREATE TEMP TRIGGER TestTempTrigger INSERT ON Test BEGIN SELECT COUNT(*) FROM Test; END;", "SQLITE_CREATE_TEMP_TRIGGER");
57     executeStatement(tx, "CREATE TEMP VIEW TestTempView AS SELECT COUNT(*) FROM Test;", "SQLITE_CREATE_TEMP_VIEW");
58     executeStatement(tx, "CREATE TRIGGER TestTrigger INSERT ON Test BEGIN SELECT COUNT(*) FROM Test; END;", "SQLITE_CREATE_TRIGGER");
59     executeStatement(tx, "CREATE VIEW TestView AS SELECT COUNT(*) FROM Test;", "SQLITE_CREATE_VIEW");
60     executeStatement(tx, "CREATE VIRTUAL TABLE TestVirtualTable USING MissingModule;", "SQLITE_CREATE_VTABLE");
61 }
62 
63 function otherStatementsCallback(tx)
64 {
65     executeStatement(tx, "SELECT COUNT(*) FROM Test;", "SQLITE_READ");
66     executeStatement(tx, "SELECT COUNT(*) FROM Test;", "SQLITE_SELECT");
67     executeStatement(tx, "DELETE FROM Test;", "SQLITE_DELETE");
68     executeStatement(tx, "INSERT INTO Test VALUES (1);", "SQLITE_INSERT");
69     executeStatement(tx, "UPDATE Test SET Foo = 2 WHERE Foo = 1;", "SQLITE_UPDATE");
70     executeStatement(tx, "PRAGMA cache_size;", "SQLITE_PRAGMA");
71 
72     executeStatement(tx, "ALTER TABLE Test RENAME TO TestTable;", "SQLITE_ALTER_TABLE");
73     // Rename the table back to its original name
74     executeStatement(tx, "ALTER TABLE TestTable RENAME To Test;", "SQLITE_ALTER_TABLE");
75 
76     executeStatement(tx, "BEGIN TRANSACTION;", "SQLITE_TRANSACTION");
77     executeStatement(tx, "ATTACH main AS TestMain;", "SQLITE_ATTACH");
78     executeStatement(tx, "DETACH TestMain;", "SQLITE_DETACH");
79     executeStatement(tx, "REINDEX;", "SQLITE_REINDEX");
80     executeStatement(tx, "ANALYZE;", "SQLITE_ANALYZE");
81 
82     // SQLITE_FUNCTION: allowed write mode
83     // There is no SQL/Javascript API to add user-defined functions to SQLite,
84     // so we cannot test this operation
85 }
86 
87 function dropStatementsCallback(tx)
88 {
89     executeStatement(tx, "DROP INDEX TestIndex;", "SQLITE_DROP_INDEX");
90 
91     // SQLITE_DROP_TEMP_INDEX: allowed in write mode
92     // Not sure how to test this: temp indexes are automatically dropped when
93     // the database is closed, but HTML5 doesn't specify a closeDatabase() call.
94 
95     executeStatement(tx, "DROP TABLE TestTempTable;", "SQLITE_DROP_TEMP_TABLE");
96     executeStatement(tx, "DROP TRIGGER TestTempTrigger;", "SQLITE_DROP_TEMP_TRIGGER");
97     executeStatement(tx, "DROP VIEW TestTempView;", "SQLITE_DROP_TEMP_VIEW");
98     executeStatement(tx, "DROP TRIGGER TestTrigger;", "SQLITE_DROP_TRIGGER");
99     executeStatement(tx, "DROP VIEW TestView;", "SQLITE_DROP_VIEW");
100 
101     // SQLITE_DROP_VTABLE: allowed in write mode
102     // Not sure how to test this: we cannot create a virtual table because we do not
103     // have SQL/Javascript APIs to register a module that implements a virtual table.
104     // Therefore, trying to drop a virtual table will always fail (no such table)
105     // before even getting to the authorizer.
106 
107     executeStatement(tx, "DROP TABLE Test;", "SQLITE_DROP_TABLE");
108 }
109 
110 function testReadWriteMode(db)
111 {
112     db.transaction(function(tx) {
113             createTableCallback(tx);
114             createStatementsCallback(tx);
115             otherStatementsCallback(tx);
116             dropStatementsCallback(tx);
117         },
118         function(error) { logAndTerminateTest("Write transaction failed", error); },
119         function() { log("Write transaction succeeded."); });
120 }
121 
122 function testReadOnlyMode(db)
123 {
124     // Test the 'CREATE TABLE' operation; it should be disallowed
125     db.readTransaction(createTableCallback,
126         function(error) { logAndTerminateTest("Read 'CREATE TABLE' transaction failed", error); });
127 
128     // In order to test all other 'CREATE' operations, we must create the table first
129     db.transaction(createTableCallback,
130         function(error) { logAndTerminateTest("Write 'CREATE TABLE' transaction failed", error); });
131     db.readTransaction(createStatementsCallback,
132         function(error) { logAndTerminateTest("Read 'CREATE' transaction failed", error); });
133 
134     // In order to test the 'DROP' and 'other' operations, we need to first create the respective entities
135     db.transaction(createStatementsCallback,
136         function(error) { logAndTerminateTest("Write 'CREATE' transaction failed", error); });
137     db.readTransaction(otherStatementsCallback,
138         function(error) { logAndTerminateTest("Read 'other' transaction failed", error); });
139 
140     // Hack: insert an empty write transaction to guaratee that these transactions are executed sequentially
141     db.transaction(function(tx) { });
142     db.readTransaction(dropStatementsCallback,
143         function(error) { logAndTerminateTest("Read 'DROP' transaction failed", error); },
144         function() { log("Read transactions succeeded."); terminateTest(); });
145 }
146 
147 function runTest()
148 {
149     var db = openDatabaseWithSuffix("AuthorizerTest", "1.0", "Tests the database authorizer.", 32768);
150     cleanup(db);
151     testReadWriteMode(db);
152     testReadOnlyMode(db);
153 }
154