summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--synapse/storage/appservice.py23
-rw-r--r--synapse/storage/schema/delta/15/appservice_txns.sql7
-rw-r--r--tests/storage/test_appservice.py38
3 files changed, 40 insertions, 28 deletions
diff --git a/synapse/storage/appservice.py b/synapse/storage/appservice.py
index a520a859d3..a8780eca1e 100644
--- a/synapse/storage/appservice.py
+++ b/synapse/storage/appservice.py
@@ -231,7 +231,8 @@ class ApplicationServiceStore(SQLBaseStore):
             url=as_info["url"],
             namespaces=as_info["namespaces"],
             hs_token=as_info["hs_token"],
-            sender=as_info["sender"]
+            sender=as_info["sender"],
+            id=as_info["as_token"]  # the token is the only unique thing here
         )
 
     def _populate_appservice_cache(self, config_files):
@@ -268,16 +269,20 @@ class ApplicationServiceTransactionStore(SQLBaseStore):
             A Deferred which resolves to a list of ApplicationServices, which
             may be empty.
         """
-        sql = (
-            "SELECT r.*, a.* FROM application_services_state AS s LEFT JOIN"
-            " application_services AS a ON a.id=s.as_id LEFT JOIN"
-            " application_services_regex AS r ON r.as_id=a.id WHERE state = ?"
-        )
-        results = yield self._execute_and_decode(
-            "get_appservices_by_state", sql, state
+        results = yield self._simple_select_list(
+            "application_services_state",
+            dict(state=state),
+            ["as_id"]
         )
         # NB: This assumes this class is linked with ApplicationServiceStore
-        defer.returnValue(self._parse_services_dict(results))
+        as_list = yield self.get_app_services()
+        services = []
+
+        for res in results:
+            for service in as_list:
+                if service.id == res["as_id"]:
+                    services.append(service)
+        defer.returnValue(services)
 
     @defer.inlineCallbacks
     def get_appservice_state(self, service):
diff --git a/synapse/storage/schema/delta/15/appservice_txns.sql b/synapse/storage/schema/delta/15/appservice_txns.sql
index 13bbb2de2e..2b27e2a429 100644
--- a/synapse/storage/schema/delta/15/appservice_txns.sql
+++ b/synapse/storage/schema/delta/15/appservice_txns.sql
@@ -14,14 +14,13 @@
  */
 
 CREATE TABLE IF NOT EXISTS application_services_state(
-    as_id INTEGER PRIMARY KEY,
+    as_id TEXT PRIMARY KEY,
     state TEXT,
-    last_txn TEXT,
-    FOREIGN KEY(as_id) REFERENCES application_services(id)
+    last_txn TEXT
 );
 
 CREATE TABLE IF NOT EXISTS application_services_txns(
-    as_id INTEGER NOT NULL,
+    as_id TEXT NOT NULL,
     txn_id INTEGER NOT NULL,
     event_ids TEXT NOT NULL,
     UNIQUE(as_id, txn_id) ON CONFLICT ROLLBACK
diff --git a/tests/storage/test_appservice.py b/tests/storage/test_appservice.py
index b856438fd2..58551e40b9 100644
--- a/tests/storage/test_appservice.py
+++ b/tests/storage/test_appservice.py
@@ -101,42 +101,48 @@ class ApplicationServiceTransactionStoreTestCase(unittest.TestCase):
 
     @defer.inlineCallbacks
     def setUp(self):
+        self.as_yaml_files = []
         self.db_pool = SQLiteMemoryDbPool()
         yield self.db_pool.prepare()
-        hs = HomeServer(
-            "test", db_pool=self.db_pool, clock=MockClock(), config=Mock()
-        )
         self.as_list = [
             {
                 "token": "token1",
                 "url": "https://matrix-as.org",
-                "id": 3
+                "id": "token1"
             },
             {
                 "token": "alpha_tok",
                 "url": "https://alpha.com",
-                "id": 5
+                "id": "alpha_tok"
             },
             {
                 "token": "beta_tok",
                 "url": "https://beta.com",
-                "id": 6
+                "id": "beta_tok"
             },
             {
                 "token": "delta_tok",
                 "url": "https://delta.com",
-                "id": 7
+                "id": "delta_tok"
             },
         ]
         for s in self.as_list:
-            yield self._add_service(s["id"], s["url"], s["token"])
-        self.store = TestTransactionStore(hs)
+            yield self._add_service(s["url"], s["token"])
 
-    def _add_service(self, as_id, url, token):
-        return self.db_pool.runQuery(
-            "INSERT INTO application_services(id, url, token) VALUES(?,?,?)",
-            (as_id, url, token)
+        hs = HomeServer(
+            "test", db_pool=self.db_pool, clock=MockClock(), config=Mock(
+                app_service_config_files=self.as_yaml_files
+            )
         )
+        self.store = TestTransactionStore(hs)
+
+    def _add_service(self, url, as_token):
+        as_yaml = dict(url=url, as_token=as_token, hs_token="something",
+                       sender="a_sender", namespaces={})
+        # use the token as the filename
+        with open(as_token, 'w') as outfile:
+            outfile.write(yaml.dump(as_yaml))
+            self.as_yaml_files.append(as_token)
 
     def _set_state(self, id, state, txn=None):
         return self.db_pool.runQuery(
@@ -388,8 +394,10 @@ class ApplicationServiceTransactionStoreTestCase(unittest.TestCase):
             ApplicationServiceState.DOWN
         )
         self.assertEquals(2, len(services))
-        self.assertEquals(self.as_list[2]["id"], services[0].id)
-        self.assertEquals(self.as_list[0]["id"], services[1].id)
+        self.assertEquals(
+            set([self.as_list[2]["id"], self.as_list[0]["id"]]),
+            set([services[0].id, services[1].id])
+        )
 
 
 # required for ApplicationServiceTransactionStoreTestCase tests