~launchpad-pqm/launchpad/devel

2839.4.13 by Stuart Bishop
Add basic tests
1
-- Create tables used by the Z3 PostgreSQL session storage.
2
--
3
-- The PostgreSQL user that the session machinery connects as needs to be
3691.52.1 by Stuart Bishop
Tweak session.sql session database setup script
4
-- granted the following permissions to the user the Zope 3 session machinery
5
-- is configured to connect as:
2839.4.13 by Stuart Bishop
Add basic tests
6
--   GRANT SELECT, INSERT, UPDATE, DELETE ON SessionData TO z3session;
3691.52.1 by Stuart Bishop
Tweak session.sql session database setup script
7
--   GRANT SELECT, INSERT, UPDATE, DELETE oN SessionPkgData TO z3session;
2839.4.13 by Stuart Bishop
Add basic tests
8
--   GRANT SELECT ON Secret TO z3session;
9
2839.4.8 by Stuart Bishop
Automatically build session database
10
SET client_min_messages=ERROR;
2839.4.7 by Stuart Bishop
Make CookieClientIdManager secret persistent, needed because our CookieClientIdManager isn't itself persistent
11
3691.52.1 by Stuart Bishop
Tweak session.sql session database setup script
12
CREATE TABLE Secret (secret text) WITHOUT OIDS;
2839.4.13 by Stuart Bishop
Add basic tests
13
COMMENT ON TABLE Secret IS 'The Zope3 session machinery uses a secret to cryptographically sign the tokens, stopping people creating arbitrary tokens and detecting corrupt or modified tokens. This secret is stored in this table where it can be accessed by all Z3 instances using the database';
14
2839.4.7 by Stuart Bishop
Make CookieClientIdManager secret persistent, needed because our CookieClientIdManager isn't itself persistent
15
INSERT INTO Secret VALUES ('thooper thpetial theqwet');
16
17
CREATE TABLE SessionData (
18
    client_id     text PRIMARY KEY,
2976.2.5 by Stuart Bishop
Improve session database schema
19
    created       timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
20
    last_accessed timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP
21
    ) WITHOUT OIDS;
2839.4.13 by Stuart Bishop
Add basic tests
22
COMMENT ON TABLE SessionData IS 'Stores session tokens (the client_id) and the last accessed timestamp. The precision of the last access time is dependant on configuration in the Z3 application servers.';
2839.4.7 by Stuart Bishop
Make CookieClientIdManager secret persistent, needed because our CookieClientIdManager isn't itself persistent
23
2839.4.8 by Stuart Bishop
Automatically build session database
24
CREATE INDEX sessiondata_last_accessed_idx ON SessionData(last_accessed);
25
2839.4.7 by Stuart Bishop
Make CookieClientIdManager secret persistent, needed because our CookieClientIdManager isn't itself persistent
26
CREATE TABLE SessionPkgData (
2839.4.11 by Stuart Bishop
Implement sweeping
27
    client_id  text NOT NULL
28
        REFERENCES SessionData(client_id) ON DELETE CASCADE,
2839.4.7 by Stuart Bishop
Make CookieClientIdManager secret persistent, needed because our CookieClientIdManager isn't itself persistent
29
    product_id text NOT NULL,
30
    key        text NOT NULL,
31
    pickle     bytea NOT NULL,
4990.1.21 by Stuart Bishop
Add missing primary keys and add db constraint stopping creation of bugs with huge descriptions
32
    CONSTRAINT sessionpkgdata_pkey PRIMARY KEY (client_id, product_id, key)
2976.2.5 by Stuart Bishop
Improve session database schema
33
    ) WITHOUT OIDS;
2839.4.13 by Stuart Bishop
Add basic tests
34
COMMENT ON TABLE SessionPkgData IS 'Stores the actual session data as a Python pickle.';
2839.4.7 by Stuart Bishop
Make CookieClientIdManager secret persistent, needed because our CookieClientIdManager isn't itself persistent
35
3691.52.3 by Stuart Bishop
Fix Bug 46149, moving upserts to stored procedures
36
CREATE OR REPLACE FUNCTION ensure_session_client_id(p_client_id text)
37
RETURNS VOID AS $$
38
BEGIN
39
    INSERT INTO SessionData (client_id) VALUES (p_client_id);
40
EXCEPTION WHEN unique_violation THEN
41
    -- Do nothing
42
END;
43
$$ LANGUAGE plpgsql;
44
45
CREATE OR REPLACE FUNCTION set_session_pkg_data(
46
    p_client_id text, p_product_id text, p_key text, p_pickle bytea
47
    ) RETURNS VOID AS $$
48
BEGIN
3691.126.1 by Stuart Bishop
Use standard and more bulletproof upsert loop for session storage
49
    -- Standard upsert loop to avoid race conditions
50
    LOOP
51
        -- Attempt an UPDATE first
3691.52.3 by Stuart Bishop
Fix Bug 46149, moving upserts to stored procedures
52
        UPDATE SessionPkgData SET pickle = p_pickle
53
        WHERE client_id = p_client_id
54
            AND product_id = p_product_id
55
            AND key = p_key;
3691.126.1 by Stuart Bishop
Use standard and more bulletproof upsert loop for session storage
56
        IF found THEN
57
            RETURN;
3691.52.3 by Stuart Bishop
Fix Bug 46149, moving upserts to stored procedures
58
        END IF;
3691.126.1 by Stuart Bishop
Use standard and more bulletproof upsert loop for session storage
59
60
        -- Next try an insert
61
        BEGIN
62
            INSERT INTO SessionPkgData (client_id, product_id, key, pickle)
63
            VALUES (p_client_id, p_product_id, p_key, p_pickle);
64
            RETURN;
65
66
        -- If the INSERT fails, another connection did the INSERT before us
67
        -- so ignore and try update again next loop.
68
        EXCEPTION WHEN unique_violation THEN
69
            -- Do nothing
70
        END;
71
    END LOOP;
3691.52.3 by Stuart Bishop
Fix Bug 46149, moving upserts to stored procedures
72
END;
73
$$ LANGUAGE plpgsql;
74