diff --git a/src/rust/db/migrations/00000000000000_diesel_initial_setup/down.sql b/src/rust/db/migrations/00000000000000_diesel_initial_setup/down.sql index b6e90a911..be2e4a35c 100644 --- a/src/rust/db/migrations/00000000000000_diesel_initial_setup/down.sql +++ b/src/rust/db/migrations/00000000000000_diesel_initial_setup/down.sql @@ -1,6 +1,6 @@ -- This file was automatically created by Diesel to setup helper functions -- and other internal bookkeeping. This file is safe to edit, any future -- changes will be added to existing projects as new migrations. -DROP FUNCTION IF EXISTS diesel_manage_updated_at (_tbl regclass); +drop function if exists diesel_manage_updated_at (_tbl regclass); -DROP FUNCTION IF EXISTS diesel_set_updated_at (); +drop function if exists diesel_set_updated_at (); diff --git a/src/rust/db/migrations/00000000000000_diesel_initial_setup/up.sql b/src/rust/db/migrations/00000000000000_diesel_initial_setup/up.sql index 11b8a42a1..ea15ef0a0 100644 --- a/src/rust/db/migrations/00000000000000_diesel_initial_setup/up.sql +++ b/src/rust/db/migrations/00000000000000_diesel_initial_setup/up.sql @@ -15,24 +15,24 @@ -- -- SELECT diesel_manage_updated_at('users'); -- ``` -CREATE OR REPLACE FUNCTION diesel_manage_updated_at (_tbl regclass) - RETURNS void - AS $$ -BEGIN - EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s +create or replace function diesel_manage_updated_at (_tbl regclass) + returns void + as $$ +begin + execute format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); -END; +end; $$ -LANGUAGE plpgsql; +language plpgsql; -CREATE OR REPLACE FUNCTION diesel_set_updated_at () - RETURNS TRIGGER - AS $$ -BEGIN - IF (NEW IS DISTINCT FROM OLD AND NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at) THEN - NEW.updated_at := CURRENT_TIMESTAMP; - END IF; - RETURN NEW; -END; +create or replace function diesel_set_updated_at () + returns trigger + as $$ +begin + if (NEW is distinct from OLD and new.updated_at is not distinct from old.updated_at) then + new.updated_at := current_timestamp; + end if; + return NEW; +end; $$ -LANGUAGE plpgsql; +language plpgsql; diff --git a/src/rust/db/migrations/2023-03-16-025536_create_markets/down.sql b/src/rust/db/migrations/2023-03-16-025536_create_markets/down.sql index f2219ee07..480c4d496 100644 --- a/src/rust/db/migrations/2023-03-16-025536_create_markets/down.sql +++ b/src/rust/db/migrations/2023-03-16-025536_create_markets/down.sql @@ -1,15 +1,15 @@ -DROP TABLE recognized_market_events; +drop table recognized_market_events; -DROP TYPE market_event_type; +drop type market_event_type; -DROP TABLE recognized_markets; +drop table recognized_markets; -DROP TRIGGER register_market_trigger ON market_registration_events; +drop trigger register_market_trigger on market_registration_events; -DROP FUNCTION register_market; +drop function register_market; -DROP TABLE market_registration_events; +drop table market_registration_events; -DROP TABLE markets; +drop table markets; -DROP TABLE coins; +drop table coins; diff --git a/src/rust/db/migrations/2023-03-16-025536_create_markets/up.sql b/src/rust/db/migrations/2023-03-16-025536_create_markets/up.sql index 388b6ea18..e7aa00a36 100644 --- a/src/rust/db/migrations/2023-03-16-025536_create_markets/up.sql +++ b/src/rust/db/migrations/2023-03-16-025536_create_markets/up.sql @@ -1,115 +1,115 @@ -- Corresponds to aptos_std::type_info::TypeInfo and -- aptos_framework::coin::CoinInfo. GenericAsset will also be included. -CREATE TABLE coins ( - account_address varchar(70) NOT NULL, - module_name text NOT NULL, - struct_name text NOT NULL, - symbol varchar(10) NOT NULL, - name text NOT NULL, - decimals smallint NOT NULL, - PRIMARY KEY (account_address, module_name, struct_name) +create table coins ( + account_address varchar(70) not null, + module_name text not null, + struct_name text not null, + symbol varchar(10) not null, + name text not null, + decimals smallint not null, + primary key (account_address, module_name, struct_name) ); -- Corresponds to econia::registry::MarketInfo. -- Only recognized markets should be stored in the api database. -CREATE TABLE markets ( - market_id numeric(20) NOT NULL PRIMARY KEY, - name text NOT NULL, +create table markets ( + market_id numeric(20) not null primary key, + name text not null, base_account_address varchar(70), base_module_name text, base_struct_name text, base_name_generic text, - quote_account_address varchar(70) NOT NULL, - quote_module_name text NOT NULL, - quote_struct_name text NOT NULL, - lot_size numeric(20) NOT NULL, - tick_size numeric(20) NOT NULL, - min_size numeric(20) NOT NULL, - underwriter_id numeric(20) NOT NULL, - created_at timestamptz NOT NULL, - FOREIGN KEY (base_account_address, base_module_name, base_struct_name) REFERENCES coins (account_address, module_name, struct_name), - FOREIGN KEY (quote_account_address, quote_module_name, quote_struct_name) REFERENCES coins (account_address, module_name, struct_name) + quote_account_address varchar(70) not null, + quote_module_name text not null, + quote_struct_name text not null, + lot_size numeric(20) not null, + tick_size numeric(20) not null, + min_size numeric(20) not null, + underwriter_id numeric(20) not null, + created_at timestamptz not null, + foreign key (base_account_address, base_module_name, base_struct_name) references coins (account_address, module_name, struct_name), + foreign key (quote_account_address, quote_module_name, quote_struct_name) references coins (account_address, module_name, struct_name) ); -- Corresponds to econia::registry::MarketRegistrationEvent -CREATE TABLE market_registration_events ( - market_id numeric(20) NOT NULL PRIMARY KEY, - time timestamptz NOT NULL, +create table market_registration_events ( + market_id numeric(20) not null primary key, + time timestamptz not null, base_account_address varchar(70), base_module_name text, base_struct_name text, base_name_generic text, - quote_account_address varchar(70) NOT NULL, - quote_module_name text NOT NULL, - quote_struct_name text NOT NULL, - lot_size numeric(20) NOT NULL, - tick_size numeric(20) NOT NULL, - min_size numeric(20) NOT NULL, - underwriter_id numeric(20) NOT NULL, - FOREIGN KEY (market_id) REFERENCES markets (market_id) + quote_account_address varchar(70) not null, + quote_module_name text not null, + quote_struct_name text not null, + lot_size numeric(20) not null, + tick_size numeric(20) not null, + min_size numeric(20) not null, + underwriter_id numeric(20) not null, + foreign key (market_id) references markets (market_id) ); -CREATE FUNCTION register_market () - RETURNS TRIGGER - AS $register_market$ -DECLARE +create function register_market () + returns trigger + as $register_market$ +declare base_symbol varchar(8); quote_symbol varchar(8); -BEGIN - IF NEW.base_name_generic IS NULL THEN - SELECT +begin + if new.base_name_generic is null then + select symbol - FROM + from coins - WHERE - account_address = NEW.base_account_address - AND module_name = NEW.base_module_name - AND struct_name = NEW.base_struct_name INTO base_symbol; - SELECT + where + account_address = new.base_account_address + and module_name = new.base_module_name + and struct_name = new.base_struct_name into base_symbol; + select symbol - FROM + from coins - WHERE - account_address = NEW.quote_account_address - AND module_name = NEW.quote_module_name - AND struct_name = NEW.quote_struct_name INTO quote_symbol; - INSERT INTO markets - VALUES (NEW.market_id, base_symbol || '-' || quote_symbol, NEW.base_account_address, NEW.base_module_name, NEW.base_struct_name, NEW.base_name_generic, NEW.quote_account_address, NEW.quote_module_name, NEW.quote_struct_name, NEW.lot_size, NEW.tick_size, NEW.min_size, NEW.underwriter_id, NEW.time); - ELSE - INSERT INTO markets - VALUES (NEW.market_id, NEW.base_name_generic, NEW.base_account_address, NEW.base_module_name, NEW.base_struct_name, NEW.base_name_generic, NEW.quote_account_address, NEW.quote_module_name, NEW.quote_struct_name, NEW.lot_size, NEW.tick_size, NEW.min_size, NEW.underwriter_id, NEW.time); - END IF; - RETURN NEW; -END; + where + account_address = new.quote_account_address + and module_name = new.quote_module_name + and struct_name = new.quote_struct_name into quote_symbol; + insert into markets + values (new.market_id, base_symbol || '-' || quote_symbol, new.base_account_address, new.base_module_name, new.base_struct_name, new.base_name_generic, new.quote_account_address, new.quote_module_name, new.quote_struct_name, new.lot_size, new.tick_size, new.min_size, new.underwriter_id, new.time); + else + insert into markets + values (new.market_id, new.base_name_generic, new.base_account_address, new.base_module_name, new.base_struct_name, new.base_name_generic, new.quote_account_address, new.quote_module_name, new.quote_struct_name, new.lot_size, new.tick_size, new.min_size, new.underwriter_id, new.time); + end if; + return NEW; +end; $register_market$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER register_market_trigger - BEFORE INSERT ON market_registration_events - FOR EACH ROW - EXECUTE PROCEDURE register_market (); +create trigger register_market_trigger + before insert on market_registration_events + for each row + execute procedure register_market (); -- Corresponds to econia::registry::RecognizedMarketInfo -- This id does not need to exist, but diesel only supports tables -- with primary keys -CREATE TABLE recognized_markets ( - id serial NOT NULL PRIMARY KEY, - market_id numeric(20) NOT NULL, - FOREIGN KEY (market_id) REFERENCES markets (market_id) +create table recognized_markets ( + id serial not null primary key, + market_id numeric(20) not null, + foreign key (market_id) references markets (market_id) ); -- Type of events that can be emitted for a recognized market. -CREATE TYPE market_event_type AS enum ( +create type market_event_type as enum ( 'add', 'remove', 'update' ); -- Corresponds to econia::registry::RecognizedMarketEvent. -CREATE TABLE recognized_market_events ( - market_id numeric(20) NOT NULL PRIMARY KEY, - time timestamptz NOT NULL, - event_type market_event_type NOT NULL, +create table recognized_market_events ( + market_id numeric(20) not null primary key, + time timestamptz not null, + event_type market_event_type not null, lot_size numeric(20), tick_size numeric(20), min_size numeric(20) diff --git a/src/rust/db/migrations/2023-03-16-080047_order_events/down.sql b/src/rust/db/migrations/2023-03-16-080047_order_events/down.sql index 657959c6d..486308c32 100644 --- a/src/rust/db/migrations/2023-03-16-080047_order_events/down.sql +++ b/src/rust/db/migrations/2023-03-16-080047_order_events/down.sql @@ -1,23 +1,22 @@ -- TODO: need to finish this correctly +drop table fills; -DROP TABLE fills; +drop trigger handle_taker_event_trigger on taker_events; -DROP TRIGGER handle_taker_event_trigger ON taker_events; +drop function handle_taker_event; -DROP FUNCTION handle_taker_event; +drop table taker_events; -DROP TABLE taker_events; +drop trigger handle_maker_event_trigger on maker_events; -DROP TRIGGER handle_maker_event_trigger ON maker_events; +drop function handle_maker_event; -DROP FUNCTION handle_maker_event; +drop table maker_events; -DROP TABLE maker_events; +drop type maker_event_type; -DROP TYPE maker_event_type; +drop table orders; -DROP TABLE orders; +drop type order_state; -DROP TYPE order_state; - -DROP TYPE side; +drop type side; diff --git a/src/rust/db/migrations/2023-03-16-080047_order_events/up.sql b/src/rust/db/migrations/2023-03-16-080047_order_events/up.sql index 9592caba4..1050b65a7 100644 --- a/src/rust/db/migrations/2023-03-16-080047_order_events/up.sql +++ b/src/rust/db/migrations/2023-03-16-080047_order_events/up.sql @@ -1,30 +1,30 @@ -CREATE TYPE side AS enum ( +create type side as enum ( 'bid', 'ask' ); -CREATE TYPE order_state AS enum ( +create type order_state as enum ( 'open', 'filled', 'cancelled', 'evicted' ); -CREATE TYPE restriction AS enum ( +create type restriction as enum ( 'no_restriction', 'fill_or_abort', 'immediate_or_cancel', 'post_or_abort' ); -CREATE TYPE self_match_behavior AS enum ( +create type self_match_behavior as enum ( 'abort', 'cancel_both', 'cancel_maker', 'cancel_taker' ); -CREATE TYPE cancel_reason AS enum ( +create type cancel_reason as enum ( 'size_change_internal', 'eviction', 'immediate_or_cancel', @@ -35,213 +35,213 @@ CREATE TYPE cancel_reason AS enum ( 'self_match_taker' ); -CREATE TABLE orders ( - order_id numeric(39) NOT NULL, - market_id numeric(20) NOT NULL, - side side NOT NULL, - size numeric(20) NOT NULL, - remaining_size numeric(20) NOT NULL, - price numeric(20) NOT NULL, - user_address varchar(70) NOT NULL, +create table orders ( + order_id numeric(39) not null, + market_id numeric(20) not null, + side side not null, + size numeric(20) not null, + remaining_size numeric(20) not null, + price numeric(20) not null, + user_address varchar(70) not null, custodian_id numeric(20), - order_state order_state NOT NULL, - created_at timestamptz NOT NULL, - PRIMARY KEY (order_id, market_id), - FOREIGN KEY (market_id) REFERENCES markets (market_id) + order_state order_state not null, + created_at timestamptz not null, + primary key (order_id, market_id), + foreign key (market_id) references markets (market_id) ); -CREATE TABLE cancel_order_events ( - market_id numeric(20) NOT NULL, - order_id numeric(39) NOT NULL, - user_address varchar(70) NOT NULL, +create table cancel_order_events ( + market_id numeric(20) not null, + order_id numeric(39) not null, + user_address varchar(70) not null, custodian_id numeric(20), - reason cancel_reason NOT NULL, - time timestamptz NOT NULL, - PRIMARY KEY (market_id, order_id), - FOREIGN KEY (market_id) REFERENCES markets (market_id), - FOREIGN KEY (order_id, market_id) REFERENCES orders (order_id, market_id) + reason cancel_reason not null, + time timestamptz not null, + primary key (market_id, order_id), + foreign key (market_id) references markets (market_id), + foreign key (order_id, market_id) references orders (order_id, market_id) ); -CREATE FUNCTION handle_cancel_order_event () - RETURNS TRIGGER - AS $handle_cancel_order_event$ -BEGIN - UPDATE +create function handle_cancel_order_event () + returns trigger + as $handle_cancel_order_event$ +begin + update orders - SET + set order_state = 'cancelled' - WHERE - market_id = NEW.market_id - AND order_id = NEW.order_id; - RETURN new; -END; + where + market_id = new.market_id + and order_id = new.order_id; + return new; +end; $handle_cancel_order_event$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER handle_cancel_order_event_trigger - BEFORE INSERT ON cancel_order_events - FOR EACH ROW - EXECUTE PROCEDURE handle_cancel_order_event (); +create trigger handle_cancel_order_event_trigger + before insert on cancel_order_events + for each row + execute procedure handle_cancel_order_event (); -CREATE TABLE change_order_size_events ( - market_id numeric(20) NOT NULL, - order_id numeric(39) NOT NULL, - user_address varchar(70) NOT NULL, +create table change_order_size_events ( + market_id numeric(20) not null, + order_id numeric(39) not null, + user_address varchar(70) not null, custodian_id numeric(20), - side side NOT NULL, - new_size numeric(20) NOT NULL, - time timestamptz NOT NULL, - PRIMARY KEY (market_id, order_id), - FOREIGN KEY (market_id) REFERENCES markets (market_id), - FOREIGN KEY (order_id, market_id) REFERENCES orders (order_id, market_id) + side side not null, + new_size numeric(20) not null, + time timestamptz not null, + primary key (market_id, order_id), + foreign key (market_id) references markets (market_id), + foreign key (order_id, market_id) references orders (order_id, market_id) ); -CREATE FUNCTION handle_change_order_size_event () - RETURNS TRIGGER - AS $handle_change_order_size_event$ -BEGIN - UPDATE +create function handle_change_order_size_event () + returns trigger + as $handle_change_order_size_event$ +begin + update orders - SET - size = NEW.size - WHERE - market_id = NEW.market_id - AND order_id = NEW.order_id; - RETURN new; -END; + set + size = new.size + where + market_id = new.market_id + and order_id = new.order_id; + return new; +end; $handle_change_order_size_event$ -LANGUAGE plpgsql; - -CREATE TRIGGER handle_change_order_size_event_trigger - BEFORE INSERT ON change_order_size_events - FOR EACH ROW - EXECUTE PROCEDURE handle_change_order_size_event (); - -CREATE TABLE fill_events ( - market_id numeric(20) NOT NULL, - size numeric(20) NOT NULL, - price numeric(20) NOT NULL, - maker_side side NOT NULL, - maker varchar(70) NOT NULL, +language plpgsql; + +create trigger handle_change_order_size_event_trigger + before insert on change_order_size_events + for each row + execute procedure handle_change_order_size_event (); + +create table fill_events ( + market_id numeric(20) not null, + size numeric(20) not null, + price numeric(20) not null, + maker_side side not null, + maker varchar(70) not null, maker_custodian_id numeric(20), - maker_order_id numeric(39) NOT NULL, - taker varchar(70) NOT NULL, + maker_order_id numeric(39) not null, + taker varchar(70) not null, taker_custodian_id numeric(20), - taker_order_id numeric(39) NOT NULL, - taker_quote_fees_paid numeric(20) NOT NULL, - sequence_number_for_trade numeric(20) NOT NULL, - time timestamptz NOT NULL, - PRIMARY KEY (market_id, maker_order_id, taker_order_id), - FOREIGN KEY (market_id) REFERENCES markets (market_id), - FOREIGN KEY (maker_order_id, market_id) REFERENCES orders (order_id, market_id), - FOREIGN KEY (taker_order_id, market_id) REFERENCES orders (order_id, market_id) + taker_order_id numeric(39) not null, + taker_quote_fees_paid numeric(20) not null, + sequence_number_for_trade numeric(20) not null, + time timestamptz not null, + primary key (market_id, maker_order_id, taker_order_id), + foreign key (market_id) references markets (market_id), + foreign key (maker_order_id, market_id) references orders (order_id, market_id), + foreign key (taker_order_id, market_id) references orders (order_id, market_id) ); -CREATE FUNCTION handle_fill_event () - RETURNS TRIGGER - AS $handle_fill_event$ -BEGIN - UPDATE +create function handle_fill_event () + returns trigger + as $handle_fill_event$ +begin + update orders - SET - remaining_size = remaining_size - NEW.size, + set + remaining_size = remaining_size - new.size, order_state = ( - CASE WHEN remaining_size <= 0 THEN + case when remaining_size <= 0 then 'filled' - ELSE + else order_state - END) - WHERE - market_id = NEW.market_id - AND order_id = NEW.order_id; - RETURN new; -END; + end) + where + market_id = new.market_id + and order_id = new.order_id; + return new; +end; $handle_fill_event$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER handle_fill_event_trigger - BEFORE INSERT ON fill_events - FOR EACH ROW - EXECUTE PROCEDURE handle_fill_event (); +create trigger handle_fill_event_trigger + before insert on fill_events + for each row + execute procedure handle_fill_event (); -CREATE TABLE place_limit_order_events ( - market_id numeric(20) NOT NULL, - user_address varchar(70) NOT NULL, +create table place_limit_order_events ( + market_id numeric(20) not null, + user_address varchar(70) not null, custodian_id numeric(20), integrator varchar(70), - side side NOT NULL, - size numeric(20) NOT NULL, - price numeric(20) NOT NULL, - restriction restriction NOT NULL, - self_match_behavior self_match_behavior NOT NULL, - remaining_size numeric(20) NOT NULL, - order_id numeric(39) NOT NULL, - time timestamptz NOT NULL, - PRIMARY KEY (market_id, order_id), - FOREIGN KEY (market_id) REFERENCES markets (market_id), - FOREIGN KEY (order_id, market_id) REFERENCES orders (order_id, market_id) + side side not null, + size numeric(20) not null, + price numeric(20) not null, + restriction restriction not null, + self_match_behavior self_match_behavior not null, + remaining_size numeric(20) not null, + order_id numeric(39) not null, + time timestamptz not null, + primary key (market_id, order_id), + foreign key (market_id) references markets (market_id), + foreign key (order_id, market_id) references orders (order_id, market_id) ); -CREATE FUNCTION handle_place_limit_order_event () - RETURNS TRIGGER - AS $handle_place_limit_order_event$ -BEGIN - INSERT INTO orders - VALUES (NEW.order_id, NEW.market_id, NEW.side, NEW.size, NEW.remaining_size, NEW.price, NEW.user_address, NEW.custodian_id, 'open', NEW.time); - RETURN new; -END; +create function handle_place_limit_order_event () + returns trigger + as $handle_place_limit_order_event$ +begin + insert into orders + values (new.order_id, new.market_id, new.side, new.size, new.remaining_size, new.price, new.user_address, new.custodian_id, 'open', new.time); + return new; +end; $handle_place_limit_order_event$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER handle_place_limit_order_event_trigger - BEFORE INSERT ON place_limit_order_events - FOR EACH ROW - EXECUTE PROCEDURE handle_place_limit_order_event (); +create trigger handle_place_limit_order_event_trigger + before insert on place_limit_order_events + for each row + execute procedure handle_place_limit_order_event (); -CREATE TABLE place_market_order_events ( - market_id numeric(20) NOT NULL, - user_address varchar(70) NOT NULL, +create table place_market_order_events ( + market_id numeric(20) not null, + user_address varchar(70) not null, custodian_id numeric(20), integrator varchar(70), - direction side NOT NULL, - size numeric(20) NOT NULL, - self_match_behavior self_match_behavior NOT NULL, - order_id numeric(39) NOT NULL, - time timestamptz NOT NULL, - PRIMARY KEY (market_id, order_id), - FOREIGN KEY (market_id) REFERENCES markets (market_id), - FOREIGN KEY (order_id, market_id) REFERENCES orders (order_id, market_id) + direction side not null, + size numeric(20) not null, + self_match_behavior self_match_behavior not null, + order_id numeric(39) not null, + time timestamptz not null, + primary key (market_id, order_id), + foreign key (market_id) references markets (market_id), + foreign key (order_id, market_id) references orders (order_id, market_id) ); -CREATE FUNCTION handle_place_market_order_event () - RETURNS TRIGGER - AS $handle_place_market_order_event$ -BEGIN - INSERT INTO orders - VALUES (NEW.order_id, NEW.market_id, NEW.direction, NEW.size, NEW.size, NEW.remaining_size, NEW.user_address, NEW.custodian_id, 'open', NEW.time); - RETURN new; -END; +create function handle_place_market_order_event () + returns trigger + as $handle_place_market_order_event$ +begin + insert into orders + values (new.order_id, new.market_id, new.direction, new.size, new.size, new.remaining_size, new.user_address, new.custodian_id, 'open', new.time); + return new; +end; $handle_place_market_order_event$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER handle_place_market_order_event_trigger - BEFORE INSERT ON place_market_order_events - FOR EACH ROW - EXECUTE PROCEDURE handle_place_market_order_event (); +create trigger handle_place_market_order_event_trigger + before insert on place_market_order_events + for each row + execute procedure handle_place_market_order_event (); -CREATE TABLE place_swap_order_events ( - market_id numeric(20) NOT NULL, - signing_account varchar(70) NOT NULL, +create table place_swap_order_events ( + market_id numeric(20) not null, + signing_account varchar(70) not null, integrator varchar(70), - direction side NOT NULL, - min_base numeric(20) NOT NULL, - max_base numeric(20) NOT NULL, - min_quote numeric(20) NOT NULL, - max_quote numeric(20) NOT NULL, - limit_price numeric(20) NOT NULL, - order_id numeric(39) NOT NULL, - time timestamptz NOT NULL, - PRIMARY KEY (market_id, order_id), - FOREIGN KEY (market_id) REFERENCES markets (market_id), - FOREIGN KEY (order_id, market_id) REFERENCES orders (order_id, market_id) + direction side not null, + min_base numeric(20) not null, + max_base numeric(20) not null, + min_quote numeric(20) not null, + max_quote numeric(20) not null, + limit_price numeric(20) not null, + order_id numeric(39) not null, + time timestamptz not null, + primary key (market_id, order_id), + foreign key (market_id) references markets (market_id), + foreign key (order_id, market_id) references orders (order_id, market_id) ); diff --git a/src/rust/db/migrations/2023-04-03-015516_ohlc_bars/down.sql b/src/rust/db/migrations/2023-04-03-015516_ohlc_bars/down.sql index 7b66de7b1..91f06a016 100644 --- a/src/rust/db/migrations/2023-04-03-015516_ohlc_bars/down.sql +++ b/src/rust/db/migrations/2023-04-03-015516_ohlc_bars/down.sql @@ -1,25 +1,25 @@ -DROP TRIGGER handle_30m_interval_end_trigger ON bars_30m; +drop trigger handle_30m_interval_end_trigger on bars_30m; -DROP FUNCTION handle_30m_interval_end; +drop function handle_30m_interval_end; -DROP TRIGGER handle_15m_interval_end_trigger ON bars_15m; +drop trigger handle_15m_interval_end_trigger on bars_15m; -DROP FUNCTION handle_15m_interval_end; +drop function handle_15m_interval_end; -DROP TRIGGER handle_5m_interval_end_trigger ON bars_5m; +drop trigger handle_5m_interval_end_trigger on bars_5m; -DROP FUNCTION handle_5m_interval_end; +drop function handle_5m_interval_end; -DROP TRIGGER handle_1m_interval_end_trigger ON bars_1m; +drop trigger handle_1m_interval_end_trigger on bars_1m; -DROP FUNCTION handle_1m_interval_end; +drop function handle_1m_interval_end; -DROP TABLE bars_1h; +drop table bars_1h; -DROP TABLE bars_30m; +drop table bars_30m; -DROP TABLE bars_15m; +drop table bars_15m; -DROP TABLE bars_5m; +drop table bars_5m; -DROP TABLE bars_1m; +drop table bars_1m; diff --git a/src/rust/db/migrations/2023-04-03-015516_ohlc_bars/up.sql b/src/rust/db/migrations/2023-04-03-015516_ohlc_bars/up.sql index 3ac7e269b..496f8a171 100644 --- a/src/rust/db/migrations/2023-04-03-015516_ohlc_bars/up.sql +++ b/src/rust/db/migrations/2023-04-03-015516_ohlc_bars/up.sql @@ -1,287 +1,291 @@ -CREATE TABLE bars_1m ( - market_id numeric(20) NOT NULL, - start_time timestamptz NOT NULL, - open numeric(20) NOT NULL, - high numeric(20) NOT NULL, - low numeric(20) NOT NULL, - close numeric(20) NOT NULL, - volume numeric(20) NOT NULL, - PRIMARY KEY (market_id, start_time), - FOREIGN KEY (market_id) REFERENCES markets (market_id) +create table bars_1m ( + market_id numeric(20) not null, + start_time timestamptz not null, + open numeric(20) not null, + high numeric(20) not null, + low numeric(20) not null, + close numeric(20) not null, + volume numeric(20) not null, + primary key (market_id, start_time), + foreign key (market_id) references markets (market_id) ); -CREATE TABLE bars_5m ( - market_id numeric(20) NOT NULL, - start_time timestamptz NOT NULL, - open numeric(20) NOT NULL, - high numeric(20) NOT NULL, - low numeric(20) NOT NULL, - close numeric(20) NOT NULL, - volume numeric(20) NOT NULL, - PRIMARY KEY (market_id, start_time), - FOREIGN KEY (market_id) REFERENCES markets (market_id) +create table bars_5m ( + market_id numeric(20) not null, + start_time timestamptz not null, + open numeric(20) not null, + high numeric(20) not null, + low numeric(20) not null, + close numeric(20) not null, + volume numeric(20) not null, + primary key (market_id, start_time), + foreign key (market_id) references markets (market_id) ); -CREATE TABLE bars_15m ( - market_id numeric(20) NOT NULL, - start_time timestamptz NOT NULL, - open numeric(20) NOT NULL, - high numeric(20) NOT NULL, - low numeric(20) NOT NULL, - close numeric(20) NOT NULL, - volume numeric(20) NOT NULL, - PRIMARY KEY (market_id, start_time), - FOREIGN KEY (market_id) REFERENCES markets (market_id) +create table bars_15m ( + market_id numeric(20) not null, + start_time timestamptz not null, + open numeric(20) not null, + high numeric(20) not null, + low numeric(20) not null, + close numeric(20) not null, + volume numeric(20) not null, + primary key (market_id, start_time), + foreign key (market_id) references markets (market_id) ); -CREATE TABLE bars_30m ( - market_id numeric(20) NOT NULL, - start_time timestamptz NOT NULL, - open numeric(20) NOT NULL, - high numeric(20) NOT NULL, - low numeric(20) NOT NULL, - close numeric(20) NOT NULL, - volume numeric(20) NOT NULL, - PRIMARY KEY (market_id, start_time), - FOREIGN KEY (market_id) REFERENCES markets (market_id) +create table bars_30m ( + market_id numeric(20) not null, + start_time timestamptz not null, + open numeric(20) not null, + high numeric(20) not null, + low numeric(20) not null, + close numeric(20) not null, + volume numeric(20) not null, + primary key (market_id, start_time), + foreign key (market_id) references markets (market_id) ); -CREATE TABLE bars_1h ( - market_id numeric(20) NOT NULL, - start_time timestamptz NOT NULL, - open numeric(20) NOT NULL, - high numeric(20) NOT NULL, - low numeric(20) NOT NULL, - close numeric(20) NOT NULL, - volume numeric(20) NOT NULL, - PRIMARY KEY (market_id, start_time), - FOREIGN KEY (market_id) REFERENCES markets (market_id) +create table bars_1h ( + market_id numeric(20) not null, + start_time timestamptz not null, + open numeric(20) not null, + high numeric(20) not null, + low numeric(20) not null, + close numeric(20) not null, + volume numeric(20) not null, + primary key (market_id, start_time), + foreign key (market_id) references markets (market_id) ); -CREATE FUNCTION handle_1m_interval_end () - RETURNS TRIGGER - AS $handle_1m_interval_end$ -DECLARE +create function handle_1m_interval_end () + returns trigger + as $handle_1m_interval_end$ +declare interval_rows bars_1m%rowtype; -BEGIN - IF date_part('minute', NEW.start_time)::int % 5 = 4 THEN - WITH bars AS ( - SELECT +begin + if date_part('minute', new.start_time)::int % 5 = 4 then + with bars as ( + select * - FROM + from bars_1m - WHERE - start_time > NEW.start_time - '4 minutes'::interval - '1 second'::interval - AND start_time <= NEW.start_time - AND market_id = NEW.market_id + where + start_time > new.start_time - '4 minutes'::interval - '1 second'::interval + and start_time <= new.start_time + and market_id = new.market_id ), -FIRST AS ( - SELECT +first as ( + select start_time, - first_value(OPEN) OVER (ORDER BY start_time) AS open -FROM + first_value(open) over (order by start_time) as open +from bars ), -LAST AS ( - SELECT +last as ( + select start_time, - first_value(CLOSE) OVER (ORDER BY start_time DESC) AS close -FROM + first_value(close) over (order by start_time desc) as close +from bars ) -SELECT +select bars.market_id, min(first.start_time), - min(first.open) AS open, - max(high) AS high, - min(low) AS low, - min(last.close) AS close, - sum(volume) AS volume -FROM + min(first.open) as open, + max(high) as high, + min(low) as low, + min(last.close) as close, + sum(volume) as volume +from bars - INNER JOIN FIRST ON bars.start_time = first.start_time - INNER JOIN LAST ON bars.start_time = last.start_time -GROUP BY - bars.market_id INTO interval_rows; -INSERT INTO bars_5m - VALUES (interval_rows.market_id, interval_rows.start_time, interval_rows.open, interval_rows.high, interval_rows.low, interval_rows.close, interval_rows.volume); -END IF; - RETURN new; -END; + inner join first on bars.start_time = first.start_time + inner join last on bars.start_time = last.start_time +group by + bars.market_id into interval_rows; +insert into bars_5m + values (interval_rows.market_id, interval_rows.start_time, interval_rows.open, interval_rows.high, interval_rows.low, interval_rows.close, interval_rows.volume); +end if; + return new; +end; $handle_1m_interval_end$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER handle_1m_interval_end_trigger - AFTER INSERT ON bars_1m FOR EACH ROW - EXECUTE PROCEDURE handle_1m_interval_end (); +create trigger handle_1m_interval_end_trigger + after insert on bars_1m + for each row + execute procedure handle_1m_interval_end (); -CREATE FUNCTION handle_5m_interval_end () - RETURNS TRIGGER - AS $handle_5m_interval_end$ -DECLARE +create function handle_5m_interval_end () + returns trigger + as $handle_5m_interval_end$ +declare interval_rows bars_5m%rowtype; -BEGIN - IF date_part('minute', NEW.start_time)::int % 15 = 10 THEN - WITH bars AS ( - SELECT +begin + if date_part('minute', new.start_time)::int % 15 = 10 then + with bars as ( + select * - FROM + from bars_5m - WHERE - start_time > NEW.start_time - '10 minutes'::interval - '1 second'::interval - AND start_time <= NEW.start_time - AND market_id = NEW.market_id + where + start_time > new.start_time - '10 minutes'::interval - '1 second'::interval + and start_time <= new.start_time + and market_id = new.market_id ), -FIRST AS ( - SELECT +first as ( + select start_time, - first_value(OPEN) OVER (ORDER BY start_time) AS open -FROM + first_value(open) over (order by start_time) as open +from bars ), -LAST AS ( - SELECT +last as ( + select start_time, - first_value(CLOSE) OVER (ORDER BY start_time DESC) AS close -FROM + first_value(close) over (order by start_time desc) as close +from bars ) -SELECT +select bars.market_id, min(first.start_time), - min(first.open) AS open, - max(high) AS high, - min(low) AS low, - min(last.close) AS close, - sum(volume) AS volume -FROM + min(first.open) as open, + max(high) as high, + min(low) as low, + min(last.close) as close, + sum(volume) as volume +from bars - INNER JOIN FIRST ON bars.start_time = first.start_time - INNER JOIN LAST ON bars.start_time = last.start_time -GROUP BY - bars.market_id INTO interval_rows; -INSERT INTO bars_15m - VALUES (interval_rows.market_id, interval_rows.start_time, interval_rows.open, interval_rows.high, interval_rows.low, interval_rows.close, interval_rows.volume); -END IF; - RETURN new; -END; + inner join first on bars.start_time = first.start_time + inner join last on bars.start_time = last.start_time +group by + bars.market_id into interval_rows; +insert into bars_15m + values (interval_rows.market_id, interval_rows.start_time, interval_rows.open, interval_rows.high, interval_rows.low, interval_rows.close, interval_rows.volume); +end if; + return new; +end; $handle_5m_interval_end$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER handle_5m_interval_end_trigger - AFTER INSERT ON bars_5m FOR EACH ROW - EXECUTE PROCEDURE handle_5m_interval_end (); +create trigger handle_5m_interval_end_trigger + after insert on bars_5m + for each row + execute procedure handle_5m_interval_end (); -CREATE FUNCTION handle_15m_interval_end () - RETURNS TRIGGER - AS $handle_15m_interval_end$ -DECLARE +create function handle_15m_interval_end () + returns trigger + as $handle_15m_interval_end$ +declare interval_rows bars_15m%rowtype; -BEGIN - IF date_part('minute', NEW.start_time)::int % 30 = 15 THEN - WITH bars AS ( - SELECT +begin + if date_part('minute', new.start_time)::int % 30 = 15 then + with bars as ( + select * - FROM + from bars_15m - WHERE - start_time > NEW.start_time - '15 minutes'::interval - '1 second'::interval - AND start_time <= NEW.start_time - AND market_id = NEW.market_id + where + start_time > new.start_time - '15 minutes'::interval - '1 second'::interval + and start_time <= new.start_time + and market_id = new.market_id ), -FIRST AS ( - SELECT +first as ( + select start_time, - first_value(OPEN) OVER (ORDER BY start_time) AS open -FROM + first_value(open) over (order by start_time) as open +from bars ), -LAST AS ( - SELECT +last as ( + select start_time, - first_value(CLOSE) OVER (ORDER BY start_time DESC) AS close -FROM + first_value(close) over (order by start_time desc) as close +from bars ) -SELECT +select bars.market_id, min(first.start_time), - min(first.open) AS open, - max(high) AS high, - min(low) AS low, - min(last.close) AS close, - sum(volume) AS volume -FROM + min(first.open) as open, + max(high) as high, + min(low) as low, + min(last.close) as close, + sum(volume) as volume +from bars - INNER JOIN FIRST ON bars.start_time = first.start_time - INNER JOIN LAST ON bars.start_time = last.start_time -GROUP BY - bars.market_id INTO interval_rows; -INSERT INTO bars_30m - VALUES (interval_rows.market_id, interval_rows.start_time, interval_rows.open, interval_rows.high, interval_rows.low, interval_rows.close, interval_rows.volume); -END IF; - RETURN new; -END; + inner join first on bars.start_time = first.start_time + inner join last on bars.start_time = last.start_time +group by + bars.market_id into interval_rows; +insert into bars_30m + values (interval_rows.market_id, interval_rows.start_time, interval_rows.open, interval_rows.high, interval_rows.low, interval_rows.close, interval_rows.volume); +end if; + return new; +end; $handle_15m_interval_end$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER handle_15m_interval_end_trigger - AFTER INSERT ON bars_15m FOR EACH ROW - EXECUTE PROCEDURE handle_15m_interval_end (); +create trigger handle_15m_interval_end_trigger + after insert on bars_15m + for each row + execute procedure handle_15m_interval_end (); -CREATE FUNCTION handle_30m_interval_end () - RETURNS TRIGGER - AS $handle_30m_interval_end$ -DECLARE +create function handle_30m_interval_end () + returns trigger + as $handle_30m_interval_end$ +declare interval_rows bars_30m%rowtype; -BEGIN - IF date_part('minute', NEW.start_time)::int = 30 THEN - WITH bars AS ( - SELECT +begin + if date_part('minute', new.start_time)::int = 30 then + with bars as ( + select * - FROM + from bars_30m - WHERE - start_time > NEW.start_time - '30 minutes'::interval - '1 second'::interval - AND start_time <= NEW.start_time - AND market_id = NEW.market_id + where + start_time > new.start_time - '30 minutes'::interval - '1 second'::interval + and start_time <= new.start_time + and market_id = new.market_id ), -FIRST AS ( - SELECT +first as ( + select start_time, - first_value(OPEN) OVER (ORDER BY start_time) AS open -FROM + first_value(open) over (order by start_time) as open +from bars ), -LAST AS ( - SELECT +last as ( + select start_time, - first_value(CLOSE) OVER (ORDER BY start_time DESC) AS close -FROM + first_value(close) over (order by start_time desc) as close +from bars ) -SELECT +select bars.market_id, min(first.start_time), - min(first.open) AS open, - max(high) AS high, - min(low) AS low, - min(last.close) AS close, - sum(volume) AS volume -FROM + min(first.open) as open, + max(high) as high, + min(low) as low, + min(last.close) as close, + sum(volume) as volume +from bars - INNER JOIN FIRST ON bars.start_time = first.start_time - INNER JOIN LAST ON bars.start_time = last.start_time -GROUP BY - bars.market_id INTO interval_rows; -INSERT INTO bars_1h - VALUES (interval_rows.market_id, interval_rows.start_time, interval_rows.open, interval_rows.high, interval_rows.low, interval_rows.close, interval_rows.volume); -END IF; - RETURN new; -END; + inner join first on bars.start_time = first.start_time + inner join last on bars.start_time = last.start_time +group by + bars.market_id into interval_rows; +insert into bars_1h + values (interval_rows.market_id, interval_rows.start_time, interval_rows.open, interval_rows.high, interval_rows.low, interval_rows.close, interval_rows.volume); +end if; + return new; +end; $handle_30m_interval_end$ -LANGUAGE plpgsql; +language plpgsql; -CREATE TRIGGER handle_30m_interval_end_trigger - AFTER INSERT ON bars_30m FOR EACH ROW - EXECUTE PROCEDURE handle_30m_interval_end (); +create trigger handle_30m_interval_end_trigger + after insert on bars_30m + for each row + execute procedure handle_30m_interval_end ();