-
Notifications
You must be signed in to change notification settings - Fork 10
/
init.postgresql.dev.sql
163 lines (142 loc) · 4.55 KB
/
init.postgresql.dev.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
CREATE TABLE watchdog (
log_id SERIAL PRIMARY KEY,
function_name TEXT,
execution_timestamp TIMESTAMP WITHOUT TIME ZONE DEFAULT now(),
execution_duration INTERVAL
);
CREATE UNLOGGED TABLE clientes (
id SERIAL PRIMARY KEY,
saldo INTEGER NOT NULL DEFAULT 0
);
CREATE UNLOGGED TABLE transacoes (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
cliente_id INTEGER NOT NULL,
valor INTEGER NOT NULL,
tipo CHAR(1) NOT NULL,
descricao VARCHAR(10) NOT NULL,
realizada_em TIMESTAMP(6) NOT NULL);
CREATE INDEX idx_cliente_id ON transacoes (cliente_id);
INSERT INTO clientes(id) VALUES (DEFAULT), (DEFAULT), (DEFAULT), (DEFAULT), (DEFAULT);
CREATE EXTENSION IF NOT EXISTS pg_prewarm;
SELECT pg_prewarm('clientes');
SELECT pg_prewarm('transacoes');
WITH Percentiles AS (
SELECT
function_name,
percentile_cont(0.25) WITHIN GROUP (ORDER BY execution_duration) AS p25,
percentile_cont(0.50) WITHIN GROUP (ORDER BY execution_duration) AS p50,
percentile_cont(0.75) WITHIN GROUP (ORDER BY execution_duration) AS p75,
percentile_cont(0.95) WITHIN GROUP (ORDER BY execution_duration) AS p95
FROM
watchdog
GROUP BY
function_name
)
SELECT
function_name,
ROUND(EXTRACT(EPOCH FROM p25) * 1000, 3) AS p25ms,
ROUND(EXTRACT(EPOCH FROM p50) * 1000, 3) AS p50ms,
ROUND(EXTRACT(EPOCH FROM p75) * 1000, 3) AS p75ms,
ROUND(EXTRACT(EPOCH FROM p95) * 1000, 3) AS p95ms
FROM
Percentiles;
CREATE TYPE json_result AS (
status_code INT,
body json
);
CREATE OR REPLACE FUNCTION proc_transacao(p_shard INT, p_cliente_id INT, p_valor INT, p_tipo CHAR, p_descricao CHAR(10))
RETURNS json_result as $$
DECLARE
diff INT;
v_saldo INT;
v_limite INT;
result json_result;
start_time TIMESTAMP;
end_time TIMESTAMP;
BEGIN
start_time := clock_timestamp();
-- SELECT limite_cliente(p_cliente_id) INTO v_limite;
v_limite := CASE p_cliente_id
WHEN 1 THEN 100000
WHEN 2 THEN 80000
WHEN 3 THEN 1000000
WHEN 4 THEN 10000000
WHEN 5 THEN 500000
ELSE -1 -- Valor padrão caso o id do cliente não esteja entre 1 e 5
END;
SELECT saldo
INTO v_saldo
FROM clientes
WHERE id = p_cliente_id
FOR UPDATE;
IF p_tipo = 'd' AND ((v_saldo - p_valor) < (-1 * v_limite)) THEN
result.body := 'LIMITE_INDISPONIVEL';
result.status_code := 422;
RETURN result;
END IF;
INSERT INTO transacoes
(cliente_id, valor, tipo, descricao, realizada_em)
VALUES (p_cliente_id, p_valor, p_tipo, p_descricao, now());
UPDATE clientes
SET saldo = CASE
WHEN p_tipo = 'c' THEN saldo + p_valor
WHEN p_tipo = 'd' THEN saldo - p_valor
ELSE saldo
END
WHERE id = p_cliente_id
RETURNING saldo INTO v_saldo;
SELECT json_build_object(
'saldo', v_saldo,
'limite', v_limite
) into result.body;
result.status_code := 200;
end_time := clock_timestamp();
INSERT INTO watchdog(function_name, execution_duration) VALUES ('proc_transacao', end_time - start_time);
RETURN result;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION proc_extrato(p_cliente_id int)
RETURNS json_result AS $$
DECLARE
result json_result;
row_count integer;
v_saldo numeric;
v_limite numeric;
start_time TIMESTAMP;
end_time TIMESTAMP;
BEGIN
start_time := clock_timestamp();
SELECT saldo
INTO v_saldo
FROM clientes
WHERE id = p_cliente_id;
v_limite := CASE p_cliente_id
WHEN 1 THEN 100000
WHEN 2 THEN 80000
WHEN 3 THEN 1000000
WHEN 4 THEN 10000000
WHEN 5 THEN 500000
ELSE -1 -- Valor padrão caso o id do cliente não esteja entre 1 e 5
END;
SELECT json_build_object(
'saldo', json_build_object(
'total', v_saldo,
'data_extrato', TO_CHAR(now(), 'YYYY-MM-DD HH:MI:SS.US'),
'limite', v_limite
),
'ultimas_transacoes', COALESCE((
SELECT json_agg(row_to_json(t)) FROM (
SELECT valor, tipo, descricao
FROM transacoes
WHERE cliente_id = p_cliente_id
ORDER BY realizada_em DESC
LIMIT 10
) t
), '[]')
) INTO result.body;
result.status_code := 200;
end_time := clock_timestamp();
INSERT INTO watchdog(function_name, execution_duration) VALUES ('proc_extrato', end_time - start_time);
RETURN result;
END;
$$ LANGUAGE plpgsql;