Last active
October 3, 2020 23:33
-
-
Save omerkoseoglu/ba37ec9a4a45f6e9606d0085abc4ab2b to your computer and use it in GitHub Desktop.
PostgreSQL Merkez Bankası Döviz Kurları Stored Procedure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- auto-generated definition | |
create table exchanges | |
( | |
id uuid default uuid_generate_v4() not null | |
constraint exchanges_pk | |
primary key, | |
currency_id uuid | |
constraint exchanges_currencies_id_fk | |
references currencies | |
on delete restrict, | |
date date not null, | |
unit integer not null, | |
forex_buying double precision, | |
forex_selling double precision, | |
banknote_buying double precision, | |
banknot_selling double precision, | |
reference_id uuid | |
); | |
alter table exchanges | |
owner to postgres; | |
create unique index exchanges_currency_id_date_uindex | |
on exchanges (currency_id, date); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create table raw_data | |
( | |
id uuid default uuid_generate_v4() not null | |
constraint raw_data_pk | |
primary key, | |
created_date timestamp default now() not null, | |
data json not null, | |
exchange_date date not null, | |
request_date date not null | |
); | |
alter table raw_data | |
owner to postgres; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create or replace procedure get_exchange_rates(request_date date) | |
language plpgsql | |
as $$ | |
declare | |
data jsonb; | |
err_context text; | |
exchange_date text; | |
url varchar; | |
begin | |
if date_cmp(request_date, current_date) >= 1 then | |
RAISE EXCEPTION 'Date cannot be greater than today.'; | |
end if; | |
if date_cmp(request_date, current_date) = 0 then | |
url:= 'https://www.tcmb.gov.tr/kurlar/today.xml'; | |
else | |
url:= 'http://www.tcmb.gov.tr/kurlar/' || date_part('year', request_date) || to_char(request_date, 'mm') || '/' || to_char(request_date, 'dd') || to_char(request_date, 'mm') || date_part('year', request_date) || '.xml'; | |
end if; | |
data:= get(url); | |
if data is null then | |
RAISE EXCEPTION 'Data not found.'; | |
end if; | |
exchange_date:= data::jsonb->'Tarih_Date'->>'@Tarih'; | |
insert into raw_data (request_date, exchange_date, data) VALUES (request_date, to_date(exchange_date, 'DD.MMM.YYYY'), data->'Tarih_Date'->'Currency'); | |
exception | |
when others then | |
GET STACKED DIAGNOSTICS err_context = PG_EXCEPTION_CONTEXT; | |
RAISE INFO 'Error Name:%',SQLERRM; | |
RAISE INFO 'Error State:%', SQLSTATE; | |
RAISE INFO 'Error Context:%', err_context; | |
end; | |
$$ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create function get(uri character varying) returns json | |
language plpython3u | |
as | |
$$ | |
import json | |
import urllib3 | |
from xmltodict import parse | |
http = urllib3.PoolManager() | |
r = http.request('GET', uri) | |
try: | |
return json.dumps(parse(r.data)) | |
except: | |
return; | |
$$; | |
alter function get(varchar) owner to postgres; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
create or replace procedure transform_exchange_rate(process_date date) | |
language plpgsql | |
as $$ | |
declare | |
rec record; | |
err_context text; | |
begin | |
SELECT | |
t.exchange_date, | |
t.data as data | |
into rec | |
FROM ( | |
SELECT | |
rd.exchange_date, | |
rd.data | |
FROM raw_data rd | |
WHERE rd.exchange_date = process_date LIMIT 1 | |
) t; | |
IF rec IS NOT NULL THEN | |
begin | |
INSERT INTO exchanges (currency_id, date, unit, forex_buying, forex_selling, banknote_buying, banknot_selling) | |
SELECT | |
c.id, | |
rec.exchange_date, | |
(d#>>'{Unit}')::integer, | |
(d#>>'{ForexBuying}')::double precision, | |
(d#>>'{ForexSelling}')::double precision, | |
(d#>>'{BanknoteBuying}')::double precision, | |
(d#>>'{BanknoteSelling}')::double precision | |
FROM currencies c | |
INNER JOIN LATERAL json_array_elements(rec.data) d ON (d->>'@Kod') = c.code; | |
exception | |
when others then | |
GET STACKED DIAGNOSTICS err_context = PG_EXCEPTION_CONTEXT; | |
RAISE INFO 'Error Name:%',SQLERRM; | |
RAISE INFO 'Error State:%', SQLSTATE; | |
RAISE INFO 'Error Context:%', err_context; | |
end; | |
ELSE | |
INSERT INTO exchanges(currency_id, date, unit, forex_buying, forex_selling, banknote_buying, banknot_selling, reference_id) | |
SELECT e.currency_id, process_date, e.unit, e.forex_buying, e.forex_selling, e.banknote_buying, e.banknot_selling, e.id | |
FROM exchanges e | |
WHERE e.date = ( | |
SELECT max(e.date) max_date | |
FROM exchanges e | |
WHERE e.date <= process_date and (process_date - e.date) between 1 and 10 and e.reference_id IS NULL | |
); | |
END IF; | |
end; $$; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment