schema: add v3, rename nameplates.id to .name
This commit is contained in:
parent
6d00576ee4
commit
74a1902fcd
|
@ -16,7 +16,7 @@ def get_upgrader(new_version):
|
|||
"db-schemas/upgrade-to-v%d.sql" % new_version)
|
||||
return schema_bytes.decode("utf-8")
|
||||
|
||||
TARGET_VERSION = 2
|
||||
TARGET_VERSION = 3
|
||||
|
||||
def dict_factory(cursor, row):
|
||||
d = {}
|
||||
|
|
105
src/wormhole/server/db-schemas/v3.sql
Normal file
105
src/wormhole/server/db-schemas/v3.sql
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
-- note: anything which isn't an boolean, integer, or human-readable unicode
|
||||
-- string, (i.e. binary strings) will be stored as hex
|
||||
|
||||
CREATE TABLE `version`
|
||||
(
|
||||
`version` INTEGER -- contains one row, set to 3
|
||||
);
|
||||
|
||||
|
||||
-- Wormhole codes use a "nameplate": a short name which is only used to
|
||||
-- reference a specific (long-named) mailbox. The codes only use numeric
|
||||
-- nameplates, but the protocol and server allow can use arbitrary strings.
|
||||
CREATE TABLE `nameplates`
|
||||
(
|
||||
`app_id` VARCHAR,
|
||||
`name` VARCHAR,
|
||||
`mailbox_id` VARCHAR, -- really a foreign key
|
||||
`side1` VARCHAR, -- side name, or NULL
|
||||
`side2` VARCHAR, -- side name, or NULL
|
||||
`request_id` VARCHAR, -- from 'allocate' message, for future deduplication
|
||||
`crowded` BOOLEAN, -- at some point, three or more sides were involved
|
||||
`updated` INTEGER, -- time of last activity, used for pruning
|
||||
-- timing data
|
||||
`started` INTEGER, -- time when nameplace was opened
|
||||
`second` INTEGER -- time when second side opened
|
||||
);
|
||||
CREATE INDEX `nameplates_idx` ON `nameplates` (`app_id`, `name`);
|
||||
CREATE INDEX `nameplates_updated_idx` ON `nameplates` (`app_id`, `updated`);
|
||||
CREATE INDEX `nameplates_mailbox_idx` ON `nameplates` (`app_id`, `mailbox_id`);
|
||||
CREATE INDEX `nameplates_request_idx` ON `nameplates` (`app_id`, `request_id`);
|
||||
|
||||
-- Clients exchange messages through a "mailbox", which has a long (randomly
|
||||
-- unique) identifier and a queue of messages.
|
||||
CREATE TABLE `mailboxes`
|
||||
(
|
||||
`app_id` VARCHAR,
|
||||
`id` VARCHAR,
|
||||
`side1` VARCHAR, -- side name, or NULL
|
||||
`side2` VARCHAR, -- side name, or NULL
|
||||
`crowded` BOOLEAN, -- at some point, three or more sides were involved
|
||||
`first_mood` VARCHAR,
|
||||
-- timing data for the mailbox itself
|
||||
`started` INTEGER, -- time when opened
|
||||
`second` INTEGER -- time when second side opened
|
||||
);
|
||||
CREATE INDEX `mailboxes_idx` ON `mailboxes` (`app_id`, `id`);
|
||||
|
||||
CREATE TABLE `messages`
|
||||
(
|
||||
`app_id` VARCHAR,
|
||||
`mailbox_id` VARCHAR,
|
||||
`side` VARCHAR,
|
||||
`phase` VARCHAR, -- numeric or string
|
||||
`body` VARCHAR,
|
||||
`server_rx` INTEGER,
|
||||
`msg_id` VARCHAR
|
||||
);
|
||||
CREATE INDEX `messages_idx` ON `messages` (`app_id`, `mailbox_id`);
|
||||
|
||||
CREATE TABLE `nameplate_usage`
|
||||
(
|
||||
`app_id` VARCHAR,
|
||||
`started` INTEGER, -- seconds since epoch, rounded to "blur time"
|
||||
`waiting_time` INTEGER, -- seconds from start to 2nd side appearing, or None
|
||||
`total_time` INTEGER, -- seconds from open to last close/prune
|
||||
`result` VARCHAR -- happy, lonely, pruney, crowded
|
||||
-- nameplate moods:
|
||||
-- "happy": two sides open and close
|
||||
-- "lonely": one side opens and closes (no response from 2nd side)
|
||||
-- "pruney": channels which get pruned for inactivity
|
||||
-- "crowded": three or more sides were involved
|
||||
);
|
||||
CREATE INDEX `nameplate_usage_idx` ON `nameplate_usage` (`app_id`, `started`);
|
||||
|
||||
CREATE TABLE `mailbox_usage`
|
||||
(
|
||||
`app_id` VARCHAR,
|
||||
`started` INTEGER, -- seconds since epoch, rounded to "blur time"
|
||||
`total_time` INTEGER, -- seconds from open to last close
|
||||
`waiting_time` INTEGER, -- seconds from start to 2nd side appearing, or None
|
||||
`result` VARCHAR -- happy, scary, lonely, errory, pruney
|
||||
-- rendezvous moods:
|
||||
-- "happy": both sides close with mood=happy
|
||||
-- "scary": any side closes with mood=scary (bad MAC, probably wrong pw)
|
||||
-- "lonely": any side closes with mood=lonely (no response from 2nd side)
|
||||
-- "errory": any side closes with mood=errory (other errors)
|
||||
-- "pruney": channels which get pruned for inactivity
|
||||
-- "crowded": three or more sides were involved
|
||||
);
|
||||
CREATE INDEX `mailbox_usage_idx` ON `mailbox_usage` (`app_id`, `started`);
|
||||
|
||||
CREATE TABLE `transit_usage`
|
||||
(
|
||||
`started` INTEGER, -- seconds since epoch, rounded to "blur time"
|
||||
`total_time` INTEGER, -- seconds from open to last close
|
||||
`waiting_time` INTEGER, -- seconds from start to 2nd side appearing, or None
|
||||
`total_bytes` INTEGER, -- total bytes relayed (both directions)
|
||||
`result` VARCHAR -- happy, scary, lonely, errory, pruney
|
||||
-- transit moods:
|
||||
-- "errory": one side gave the wrong handshake
|
||||
-- "lonely": good handshake, but the other side never showed up
|
||||
-- "happy": both sides gave correct handshake
|
||||
);
|
||||
CREATE INDEX `transit_usage_idx` ON `transit_usage` (`started`);
|
|
@ -191,9 +191,9 @@ class AppNamespace:
|
|||
def get_nameplate_ids(self):
|
||||
db = self._db
|
||||
# TODO: filter this to numeric ids?
|
||||
c = db.execute("SELECT DISTINCT `id` FROM `nameplates`"
|
||||
c = db.execute("SELECT DISTINCT `name` FROM `nameplates`"
|
||||
" WHERE `app_id`=?", (self._app_id,))
|
||||
return set([row["id"] for row in c.fetchall()])
|
||||
return set([row["name"] for row in c.fetchall()])
|
||||
|
||||
def _find_available_nameplate_id(self):
|
||||
claimed = self.get_nameplate_ids()
|
||||
|
@ -230,7 +230,7 @@ class AppNamespace:
|
|||
assert isinstance(side, type("")), type(side)
|
||||
db = self._db
|
||||
row = db.execute("SELECT * FROM `nameplates`"
|
||||
" WHERE `app_id`=? AND `id`=?",
|
||||
" WHERE `app_id`=? AND `name`=?",
|
||||
(self._app_id, nameplate_id)).fetchone()
|
||||
if row:
|
||||
mailbox_id = row["mailbox_id"]
|
||||
|
@ -238,14 +238,14 @@ class AppNamespace:
|
|||
sr = add_side(row, side)
|
||||
except CrowdedError:
|
||||
db.execute("UPDATE `nameplates` SET `crowded`=?"
|
||||
" WHERE `app_id`=? AND `id`=?",
|
||||
" WHERE `app_id`=? AND `name`=?",
|
||||
(True, self._app_id, nameplate_id))
|
||||
db.commit()
|
||||
raise
|
||||
if sr.changed:
|
||||
db.execute("UPDATE `nameplates` SET"
|
||||
" `side1`=?, `side2`=?, `updated`=?, `second`=?"
|
||||
" WHERE `app_id`=? AND `id`=?",
|
||||
" WHERE `app_id`=? AND `name`=?",
|
||||
(sr.side1, sr.side2, when, when,
|
||||
self._app_id, nameplate_id))
|
||||
else:
|
||||
|
@ -257,7 +257,7 @@ class AppNamespace:
|
|||
else:
|
||||
mailbox_id = generate_mailbox_id()
|
||||
db.execute("INSERT INTO `nameplates`"
|
||||
" (`app_id`, `id`, `mailbox_id`, `side1`, `crowded`,"
|
||||
" (`app_id`, `name`, `mailbox_id`, `side1`, `crowded`,"
|
||||
" `updated`, `started`)"
|
||||
" VALUES(?,?,?,?,?, ?,?)",
|
||||
(self._app_id, nameplate_id, mailbox_id, side, False,
|
||||
|
@ -275,21 +275,21 @@ class AppNamespace:
|
|||
assert isinstance(side, type("")), type(side)
|
||||
db = self._db
|
||||
row = db.execute("SELECT * FROM `nameplates`"
|
||||
" WHERE `app_id`=? AND `id`=?",
|
||||
" WHERE `app_id`=? AND `name`=?",
|
||||
(self._app_id, nameplate_id)).fetchone()
|
||||
if not row:
|
||||
return
|
||||
sr = remove_side(row, side)
|
||||
if sr.empty:
|
||||
db.execute("DELETE FROM `nameplates`"
|
||||
" WHERE `app_id`=? AND `id`=?",
|
||||
" WHERE `app_id`=? AND `name`=?",
|
||||
(self._app_id, nameplate_id))
|
||||
self._summarize_nameplate_and_store(row, when, pruned=False)
|
||||
db.commit()
|
||||
elif sr.changed:
|
||||
db.execute("UPDATE `nameplates`"
|
||||
" SET `side1`=?, `side2`=?, `updated`=?"
|
||||
" WHERE `app_id`=? AND `id`=?",
|
||||
" WHERE `app_id`=? AND `name`=?",
|
||||
(sr.side1, sr.side2, when,
|
||||
self._app_id, nameplate_id))
|
||||
db.commit()
|
||||
|
@ -475,7 +475,7 @@ class AppNamespace:
|
|||
for row in db.execute("SELECT * FROM `nameplates`"
|
||||
" WHERE `app_id`=?",
|
||||
(self._app_id,)).fetchall():
|
||||
nameplate_id = row["id"]
|
||||
nameplate_id = row["name"]
|
||||
all_nameplate_rows[nameplate_id] = row
|
||||
if row["updated"] > old:
|
||||
which = NEW
|
||||
|
@ -500,7 +500,7 @@ class AppNamespace:
|
|||
row = all_nameplate_rows[nameplate_id]
|
||||
self._summarize_nameplate_and_store(row, now, pruned=True)
|
||||
db.execute("DELETE FROM `nameplates`"
|
||||
" WHERE `app_id`=? AND `id`=?",
|
||||
" WHERE `app_id`=? AND `name`=?",
|
||||
(self._app_id, nameplate_id))
|
||||
modified = True
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ class Server(ServerBase, unittest.TestCase):
|
|||
|
||||
def _nameplate(self, app, nameplate_id):
|
||||
return app._db.execute("SELECT * FROM `nameplates`"
|
||||
" WHERE `app_id`='appid' AND `id`=?",
|
||||
" WHERE `app_id`='appid' AND `name`=?",
|
||||
(nameplate_id,)).fetchone()
|
||||
|
||||
def test_nameplate(self):
|
||||
|
@ -355,7 +355,7 @@ class Prune(unittest.TestCase):
|
|||
|
||||
rv.prune(now=123, old=50)
|
||||
|
||||
nameplates = set([row["id"] for row in
|
||||
nameplates = set([row["name"] for row in
|
||||
db.execute("SELECT * FROM `nameplates`").fetchall()])
|
||||
self.assertEqual(new_nameplates, nameplates)
|
||||
mailboxes = set([row["id"] for row in
|
||||
|
@ -439,7 +439,7 @@ class Prune(unittest.TestCase):
|
|||
|
||||
rv.prune(now=123, old=50)
|
||||
|
||||
nameplates = set([row["id"] for row in
|
||||
nameplates = set([row["name"] for row in
|
||||
db.execute("SELECT * FROM `nameplates`").fetchall()])
|
||||
self.assertEqual(nameplate_survives, bool(nameplates),
|
||||
("nameplate", nameplate_survives, nameplates, desc))
|
||||
|
@ -725,7 +725,7 @@ class WebSocketAPI(ServerBase, unittest.TestCase):
|
|||
c1.send("claim", nameplate=nameplate_id) # allocate+claim is ok
|
||||
yield c1.sync()
|
||||
row = app._db.execute("SELECT * FROM `nameplates`"
|
||||
" WHERE `app_id`='appid' AND `id`=?",
|
||||
" WHERE `app_id`='appid' AND `name`=?",
|
||||
(nameplate_id,)).fetchone()
|
||||
self.assertEqual(row["side1"], "side")
|
||||
self.assertEqual(row["side2"], None)
|
||||
|
@ -797,7 +797,7 @@ class WebSocketAPI(ServerBase, unittest.TestCase):
|
|||
self.assertEqual(m["type"], "released")
|
||||
|
||||
row = app._db.execute("SELECT * FROM `nameplates`"
|
||||
" WHERE `app_id`='appid' AND `id`='np1'").fetchone()
|
||||
" WHERE `app_id`='appid' AND `name`='np1'").fetchone()
|
||||
self.assertEqual(row["side1"], "side2")
|
||||
self.assertEqual(row["side2"], None)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user