@@ -67,7 +67,7 @@ def transaction(dbconn=None):
67
67
have_returning = True
68
68
69
69
70
- def insert_and_get_pk (insert , pk , * , dbconn = None , ** params ):
70
+ def insert_and_get_pk (insert , _pk , * , dbconn = None , ** params ):
71
71
"""
72
72
Performs an insert and returns the value of the primary key by appending a RETURNING clause, if
73
73
supported, and otherwise falling back to using .lastrowid.
@@ -79,14 +79,35 @@ def insert_and_get_pk(insert, pk, *, dbconn=None, **params):
79
79
"""
80
80
81
81
if have_returning :
82
- insert += f" RETURNING { pk } "
82
+ insert += f" RETURNING { _pk } "
83
83
84
84
result = query (insert , dbconn = dbconn , ** params )
85
85
if have_returning :
86
86
return result .first ()[0 ]
87
87
return result .lastrowid
88
88
89
89
90
+ def insert_and_get_row (insert , _table , _pk , * , dbconn = None , ** params ):
91
+ """
92
+ Performs an insert and returned the row by appending a `RETURNING *` clause, if supported, and
93
+ otherwise fetching the row immediately after the insertion.
94
+
95
+ Takes the query, table name, and primary key column name (the latter two are needed for the
96
+ SELECT query when the db doesn't support RETURNING), and any parameters to bind.
97
+
98
+ Can optionally take the database connection by passing as a dbconn parameter (note that you may
99
+ not use "dbconn" as a bind parameter). If omitted uses web.appdb.
100
+ """
101
+
102
+ if have_returning :
103
+ insert += " RETURNING *"
104
+ return query (insert , dbconn = dbconn , ** params ).first ()
105
+
106
+ with transaction (dbconn ):
107
+ pkval = insert_and_get_pk (insert , _pk , dbconn = dbconn , ** params )
108
+ return query (f"SELECT * FROM { _table } WHERE { _pk } = :pk" , pk = pkval ).first ()
109
+
110
+
90
111
def database_init ():
91
112
"""
92
113
Perform database initialization: constructs the schema, if necessary, and performs any required
@@ -222,7 +243,35 @@ def add_new_tables(conn):
222
243
conn .execute ("CREATE INDEX user_request_nonces_expiry ON user_request_nonces(expiry)" )
223
244
224
245
added = True
225
-
246
+ if 'inbox' not in metadata .tables :
247
+ if engine .name == 'sqlite' :
248
+ conn .execute (
249
+ """
250
+ CREATE TABLE inbox (
251
+ id INTEGER PRIMARY KEY,
252
+ recipient INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
253
+ sender INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
254
+ body BLOB NOT NULL,
255
+ posted_at FLOAT DEFAULT ((julianday('now') - 2440587.5)*86400.0),
256
+ expiry FLOAT DEFAULT ((julianday('now') - 2440587.5 + 1.0)*86400.0) /* now + 24h */)
257
+ """
258
+ )
259
+ conn .execute ("CREATE INDEX inbox_recipient ON inbox(recipient)" )
260
+ else :
261
+ conn .execute (
262
+ """
263
+ CREATE TABLE inbox (
264
+ id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
265
+ recipient BIGINT NOT NULL REFERENCES users ON DELETE CASCADE,
266
+ sender BIGINT NOT NULL REFERENCES users ON DELETE CASCADE,
267
+ body BYTEA NOT NULL,
268
+ posted_at FLOAT DEFAULT (extract(epoch from now())),
269
+ expiry FLOAT DEFAULT (extract(epoch from now() + '15 days'))
270
+ )
271
+ """
272
+ )
273
+ conn .execute ("CREATE INDEX inbox_recipient ON inbox(recipient)" )
274
+ added = True
226
275
return added
227
276
228
277
0 commit comments