-
Notifications
You must be signed in to change notification settings - Fork 923
/
Copy pathinit.sql
138 lines (116 loc) · 2.65 KB
/
init.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
create unlogged table if not exists Clientes (
id serial primary key,
limite integer,
saldo integer
);
create unlogged table if not exists Transacoes (
id serial primary key,
clienteId integer not null references Clientes(id),
valor integer,
tipo char not null,
descricao varchar(10),
realizadaEm timestamp
);
create index if not exists idx_transacoes_clienteId on Transacoes(clienteId);
insert into Clientes (limite, saldo)
values
(100000, 0),
(80000, 0),
(1000000, 0),
(10000000, 0),
(500000, 0);
create type meuTipo as (codigo integer, limite integer, saldo integer);
create or replace function criarTransacao(
in clienteId integer,
in valor integer,
in tipo char,
in descricao varchar(10)
) returns meuTipo as $$
declare
cliente clientes%rowtype;
mt meuTipo;
novoSaldo integer;
begin
perform pg_advisory_xact_lock(clienteId);
select *
into cliente
from clientes
where id = clienteId;
if cliente.id is null then
mt.codigo := -1;
return mt;
end if;
if tipo = 'd' then
novoSaldo := cliente.saldo - valor;
else
novoSaldo := cliente.saldo + valor;
end if;
if novoSaldo + cliente.limite < 0 then
mt.codigo := -2;
return mt;
end if;
insert into transacoes
(valor, tipo, descricao, clienteId, realizadaEm)
values
(valor, tipo, descricao, clienteId, now()::timestamp);
update clientes
set saldo = novoSaldo
where id = clienteId;
mt.codigo := 1;
mt.limite := cliente.limite;
mt.saldo := novoSaldo;
return mt;
end;
$$ language plpgsql;
create type saldotype as (
total integer,
dataExtrato timestamp,
limite integer
);
create or replace function obterextrato(
in idCliente integer
) returns json as $$
declare
cliente clientes%rowtype;
saldo saldotype;
ultimasTransacoes json[];
begin
select *
into cliente
from clientes
where id = idCliente;
if cliente.id is null then
return json_build_object(
'codigo', -1
);
end if;
saldo.total := cliente.saldo;
saldo.dataExtrato := now()::timestamp;
saldo.limite := cliente.limite;
select array_agg(
json_build_object(
'valor', t.valor,
'tipo', t.tipo,
'descricao', t.descricao,
'realizadaEm', t.realizadaEm
) order by t.realizadaEm desc
)
into ultimasTransacoes
from (
select *
from transacoes tr
where tr.clienteId = idCliente
order by tr.realizadaEm desc
limit 10 offset 0
) as t;
return json_build_object(
'codigo', 1,
'saldo', json_build_object(
'total', saldo.total,
'dataExtrato', saldo.dataExtrato,
'limite', saldo.limite
),
'ultimasTransacoes', ultimasTransacoes
);
end;
$$ language plpgsql;