Skip to content

Commit 1b0d696

Browse files
Merge pull request #7 from express-rate-limit/feature/db-stored-procedures
Feature/db stored procedures
2 parents a8be6c3 + b9c5253 commit 1b0d696

23 files changed

+592
-179
lines changed

db/cli/run_tests.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ set -e
33
psql --quiet -U $USER -h $HOST -p $PORT -d $DATABASE -c 'CREATE EXTENSION IF NOT EXISTS pgtap;'
44

55
pg_prove -U $USER -h $HOST -p $PORT -d $DATABASE db/tests/performance/*.test.sql
6+
7+
pg_prove -U $USER -h $HOST -p $PORT -d $DATABASE db/tests/unit/*.test.sql

db/linting/lint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ echo 'Linting migrations folder'
22
sqlfluff lint source/migrations/ --dialect postgres --ignore parsing --config db/linting/.sqlfluff
33

44
echo 'Linting tests folder'
5-
sqlfluff lint db/tests/performance/ --dialect postgres --ignore parsing --config db/linting/.sqlfluff
5+
sqlfluff lint db/tests/**/ --dialect postgres --ignore parsing --config db/linting/.sqlfluff

db/tests/performance/aggregated_ip.test.sql

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,62 +26,38 @@ VALUES ('test-update', '00000000-0000-0000-0000-000000000000'::uuid, 20),
2626
('test-decrement', '00000000-0000-0000-0000-000000000000'::uuid, 30),
2727
('test-reset-key', '00000000-0000-0000-0000-000000000000'::uuid, 40);
2828

29-
PREPARE update_aggregation as
30-
INSERT INTO rate_limit.records_aggregated (key, session_id)
31-
VALUES ('test-update', '00000000-0000-0000-0000-000000000000')
32-
ON CONFLICT ON CONSTRAINT unique_session_key DO UPDATE
33-
SET count = records_aggregated.count + 1
34-
RETURNING count;
35-
3629
SELECT performs_ok(
37-
'update_aggregation',
30+
$bd$
31+
SELECT agg_increment as count FROM rate_limit.agg_increment('test-update', '00000000-0000-0000-0000-000000000000');
32+
$bd$,
3833
250,
3934
'inserting record should execute under 250ms'
4035
);
4136

42-
43-
PREPARE decrement_records as
44-
UPDATE rate_limit.records_aggregated
45-
SET count = greatest(0, count - 1)
46-
WHERE
47-
key = 'test-decrement'
48-
AND session_id = '00000000-0000-0000-0000-000000000000';
49-
5037
SELECT performs_ok(
51-
'decrement_records',
38+
$bd$
39+
SELECT * FROM rate_limit.agg_decrement('test-decrement', '00000000-0000-0000-0000-000000000000');
40+
$bd$,
5241
250,
5342
'decrementing query execute under 250ms'
5443
);
5544

56-
PREPARE reset_key as
57-
DELETE FROM rate_limit.records_aggregated
58-
WHERE
59-
key = 'test-reset-key'
60-
AND session_id = '00000000-0000-0000-0000-000000000000';
61-
62-
6345
SELECT performs_ok(
64-
'reset_key',
46+
$bd$
47+
SELECT * FROM rate_limit.agg_reset_key('test-reset-key', '00000000-0000-0000-0000-000000000000')
48+
$bd$,
6549
250,
6650
'resetting a key should execute under 250ms'
6751
);
6852

69-
PREPARE reset_all as
70-
DELETE FROM rate_limit.records_aggregated
71-
WHERE session_id = '00000000-0000-0000-0000-000000000000';
72-
73-
7453
SELECT performs_ok(
75-
'reset_all',
54+
$bd$
55+
SELECT * FROM rate_limit.agg_reset_session('00000000-0000-0000-0000-000000000000');
56+
$bd$,
7657
250,
7758
'resetting a session should execute under 250ms'
7859
);
7960

80-
DEALLOCATE update_aggregation;
81-
DEALLOCATE decrement_records;
82-
DEALLOCATE reset_key;
83-
DEALLOCATE reset_all;
84-
8561
-- Finish the tests and clean up.
8662
SELECT finish FROM finish();
8763
ROLLBACK;
Lines changed: 13 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BEGIN;
22
-- Plan the tests.
3-
SELECT plan(5);
3+
SELECT plan(4);
44

55
INSERT INTO rate_limit.sessions (name_, type_)
66
SELECT
@@ -26,79 +26,38 @@ VALUES ('test-count', '00000000-0000-0000-0000-000000000000'::uuid),
2626
('test-decrement', '00000000-0000-0000-0000-000000000000'::uuid),
2727
('test-reset-key', '00000000-0000-0000-0000-000000000000'::uuid);
2828

29-
PREPARE insert_individual_record as
30-
INSERT INTO rate_limit.individual_records (key, session_id)
31-
VALUES ('test', '00000000-0000-0000-0000-000000000000'::uuid);
32-
3329
SELECT performs_ok(
34-
'insert_individual_record',
30+
$bd$
31+
SELECT ind_increment as count FROM rate_limit.ind_increment('test-count', '00000000-0000-0000-0000-000000000000')
32+
$bd$,
3533
250,
3634
'inserting record should execute under 250ms'
3735
);
3836

39-
PREPARE retrieve_count AS
40-
SELECT count(id) AS count
41-
FROM rate_limit.individual_records
42-
WHERE
43-
key = 'test-count'
44-
AND session_id = '00000000-0000-0000-0000-000000000000'::uuid;
45-
46-
SELECT performs_ok(
47-
'retrieve_count',
48-
250,
49-
'retrieving count should execute under 250ms'
50-
);
51-
52-
53-
PREPARE decrement_records as
54-
WITH
55-
rows_to_delete AS (
56-
SELECT id FROM rate_limit.individual_records
57-
WHERE
58-
key = 'test-decrement'
59-
AND session_id = '00000000-0000-0000-0000-000000000000'
60-
ORDER BY event_time
61-
LIMIT 1
62-
)
63-
DELETE FROM rate_limit.individual_records
64-
USING rows_to_delete WHERE individual_records.id = rows_to_delete.id;
65-
6637
SELECT performs_ok(
67-
'decrement_records',
38+
$bd$
39+
SELECT * FROM rate_limit.ind_decrement('test-decrement', '00000000-0000-0000-0000-000000000000');
40+
$bd$,
6841
250,
6942
'decrementing query execute under 250ms'
7043
);
7144

72-
PREPARE reset_key as
73-
DELETE FROM rate_limit.individual_records
74-
WHERE
75-
key = 'test-reset-key'
76-
AND session_id = '00000000-0000-0000-0000-000000000000';
77-
78-
7945
SELECT performs_ok(
80-
'reset_key',
46+
$bd$
47+
SELECT * FROM rate_limit.ind_reset_key('test-reset-key', '00000000-0000-0000-0000-000000000000');
48+
$bd$,
8149
250,
8250
'resetting a key should execute under 250ms'
8351
);
8452

85-
PREPARE reset_all as
86-
DELETE FROM rate_limit.individual_records
87-
WHERE session_id = '00000000-0000-0000-0000-000000000000';
88-
89-
9053
SELECT performs_ok(
91-
'reset_all',
54+
$bd$
55+
SELECT * FROM rate_limit.ind_reset_session('00000000-0000-0000-0000-000000000000');
56+
$bd$,
9257
250,
9358
'resetting a session should execute under 250ms'
9459
);
9560

96-
DEALLOCATE insert_individual_record;
97-
DEALLOCATE retrieve_count;
98-
DEALLOCATE decrement_records;
99-
DEALLOCATE reset_key;
100-
DEALLOCATE reset_all;
101-
10261
-- Finish the tests and clean up.
10362
SELECT finish FROM finish();
10463
ROLLBACK;

db/tests/unit/agg_decrement.test.sql

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
BEGIN;
2+
-- Plan the tests.
3+
SELECT plan(2);
4+
5+
INSERT INTO rate_limit.sessions (id, name_, type_)
6+
SELECT
7+
'00000000-0000-0000-0000-000000000000'::uuid AS id,
8+
'dedicated-test'::text AS name_,
9+
'aggregated'::text AS type_;
10+
11+
INSERT INTO rate_limit.records_aggregated (key, session_id)
12+
SELECT
13+
'existing-key' AS key_,
14+
'00000000-0000-0000-0000-000000000000'::uuid AS session_id;
15+
16+
SELECT lives_ok(
17+
$have$
18+
SELECT * FROM rate_limit.agg_decrement('existing-key', '00000000-0000-0000-0000-000000000000')
19+
$have$,
20+
'rate_limit.agg_decrement does not throw an error'
21+
);
22+
23+
SELECT results_eq(
24+
$have$
25+
SELECT count FROM rate_limit.records_aggregated
26+
WHERE key = 'existing-key'
27+
$have$,
28+
$want$
29+
SELECT 0::int AS count;
30+
$want$,
31+
'rate_limit.agg_decrement decrements count for key'
32+
);
33+
34+
-- Finish the tests and clean up.
35+
SELECT finish FROM finish();
36+
ROLLBACK;

db/tests/unit/agg_increment.test.sql

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
BEGIN;
2+
-- Plan the tests.
3+
SELECT plan(2);
4+
5+
INSERT INTO rate_limit.sessions (id, name_, type_)
6+
SELECT
7+
'00000000-0000-0000-0000-000000000000'::uuid AS id,
8+
'dedicated-test'::text AS name_,
9+
'aggregated'::text AS type_;
10+
11+
INSERT INTO rate_limit.records_aggregated (key, session_id)
12+
SELECT
13+
'existing-key' AS key_,
14+
'00000000-0000-0000-0000-000000000000'::uuid AS session_id;
15+
16+
SELECT results_eq(
17+
$have$
18+
SELECT agg_increment AS count FROM rate_limit.agg_increment('new-key', '00000000-0000-0000-0000-000000000000')
19+
$have$,
20+
$want$
21+
SELECT 1::int AS count;
22+
$want$,
23+
'rate_limit.agg_increment returns correct count for new key'
24+
);
25+
26+
SELECT results_eq(
27+
$have$
28+
SELECT agg_increment AS count FROM rate_limit.agg_increment('existing-key', '00000000-0000-0000-0000-000000000000')
29+
$have$,
30+
$want$
31+
SELECT 2::int AS count;
32+
$want$,
33+
'rate_limit.agg_increment returns correct count for existing key'
34+
);
35+
36+
-- Finish the tests and clean up.
37+
SELECT finish FROM finish();
38+
ROLLBACK;

db/tests/unit/agg_reset_key.test.sql

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
BEGIN;
2+
-- Plan the tests.
3+
SELECT plan(2);
4+
5+
INSERT INTO rate_limit.sessions (id, name_, type_)
6+
SELECT
7+
'00000000-0000-0000-0000-000000000000'::uuid AS id,
8+
'dedicated-test'::text AS name_,
9+
'aggregated'::text AS type_;
10+
11+
INSERT INTO rate_limit.records_aggregated (key, session_id)
12+
SELECT
13+
'existing-key' AS key_,
14+
'00000000-0000-0000-0000-000000000000'::uuid AS session_id;
15+
16+
SELECT lives_ok(
17+
$have$
18+
SELECT * FROM rate_limit.agg_reset_key('existing-key', '00000000-0000-0000-0000-000000000000')
19+
$have$,
20+
'rate_limit.agg_reset_key does not throw an error'
21+
);
22+
23+
SELECT is_empty(
24+
$have$
25+
SELECT * FROM rate_limit.records_aggregated
26+
WHERE key = 'existing-key'
27+
$have$,
28+
'rate_limit.agg_reset_key decrements count for key'
29+
);
30+
31+
-- Finish the tests and clean up.
32+
SELECT finish FROM finish();
33+
ROLLBACK;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
BEGIN;
2+
-- Plan the tests.
3+
SELECT plan(2);
4+
5+
INSERT INTO rate_limit.sessions (id, name_, type_)
6+
SELECT
7+
'00000000-0000-0000-0000-000000000000'::uuid AS id,
8+
'dedicated-test'::text AS name_,
9+
'aggregated'::text AS type_;
10+
11+
INSERT INTO rate_limit.records_aggregated (key, session_id)
12+
SELECT
13+
'existing-key' AS key_,
14+
'00000000-0000-0000-0000-000000000000'::uuid AS session_id
15+
UNION
16+
SELECT
17+
'another-existing-key' AS key_,
18+
'00000000-0000-0000-0000-000000000000'::uuid AS session_id;
19+
20+
SELECT lives_ok(
21+
$have$
22+
SELECT * FROM rate_limit.agg_reset_session('00000000-0000-0000-0000-000000000000')
23+
$have$,
24+
'rate_limit.agg_reset_session does not throw an error'
25+
);
26+
27+
SELECT is_empty(
28+
$have$
29+
SELECT * FROM rate_limit.records_aggregated
30+
WHERE session_id = '00000000-0000-0000-0000-000000000000'
31+
$have$,
32+
'rate_limit.agg_reset_session removes all keys of session'
33+
);
34+
35+
-- Finish the tests and clean up.
36+
SELECT finish FROM finish();
37+
ROLLBACK;

db/tests/unit/ind_decrement.test.sql

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
BEGIN;
2+
-- Plan the tests.
3+
SELECT plan(2);
4+
5+
INSERT INTO rate_limit.sessions (id, name_, type_)
6+
SELECT
7+
'00000000-0000-0000-0000-000000000000'::uuid AS id,
8+
'dedicated-test'::text AS name_,
9+
'individual'::text AS type_;
10+
11+
INSERT INTO rate_limit.individual_records (key, session_id)
12+
SELECT
13+
'existing-key' AS key_,
14+
'00000000-0000-0000-0000-000000000000'::uuid AS session_id
15+
UNION ALL
16+
SELECT
17+
'existing-key' AS key_,
18+
'00000000-0000-0000-0000-000000000000'::uuid AS session_id
19+
UNION ALL
20+
SELECT
21+
'existing-key' AS key_,
22+
'00000000-0000-0000-0000-000000000000'::uuid AS session_id;
23+
24+
SELECT lives_ok(
25+
$have$
26+
SELECT * FROM rate_limit.ind_decrement('existing-key', '00000000-0000-0000-0000-000000000000')
27+
$have$,
28+
'rate_limit.ind_decrement does not throw an error'
29+
);
30+
31+
SELECT bag_eq(
32+
$have$
33+
SELECT key FROM rate_limit.individual_records
34+
WHERE session_id = '00000000-0000-0000-0000-000000000000'
35+
$have$,
36+
$want$
37+
SELECT 'existing-key'::text as key
38+
UNION ALL
39+
SELECT 'existing-key'::text as key;
40+
$want$,
41+
'rate_limit.ind_decrement applies correct logic on table rows'
42+
);
43+
44+
-- Finish the tests and clean up.
45+
SELECT finish FROM finish();
46+
ROLLBACK;

0 commit comments

Comments
 (0)