Skip to content

Commit

Permalink
Merge pull request #73 from pinknetworkx/develop
Browse files Browse the repository at this point in the history
v1.3.14
  • Loading branch information
fabian-emilius authored Jul 4, 2022
2 parents 4c59784 + bce461d commit f2c7ad3
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 87 deletions.
15 changes: 0 additions & 15 deletions definitions/materialized/atomicmarket_template_prices.sql

This file was deleted.

131 changes: 131 additions & 0 deletions definitions/migrations/1.3.14/atomicmarket.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
DROP VIEW IF EXISTS atomicmarket_template_prices_master CASCADE;

DROP TABLE IF EXISTS atomicmarket_template_prices CASCADE;
CREATE TABLE atomicmarket_template_prices (
market_contract varchar(12) not null,
assets_contract varchar(12) not null,
collection_name varchar(12),
template_id bigint not null,
symbol varchar(12) not null,
median bigint,
average bigint,
suggested_median bigint,
suggested_average bigint,
"min" bigint,
"max" bigint,
sales bigint
);


ALTER TABLE atomicmarket_template_prices
ADD constraint atomicmarket_template_prices_pkey
primary key (market_contract, assets_contract, collection_name, template_id, symbol);


CREATE INDEX IF NOT EXISTS atomicmarket_stats_markets_template_id_time ON atomicmarket_stats_markets (template_id, time);
DROP INDEX IF EXISTS atomicmarket_stats_markets_template_id;


DROP FUNCTION IF EXISTS update_atomicmarket_template_prices;
CREATE OR REPLACE FUNCTION update_atomicmarket_template_prices() RETURNS INT
LANGUAGE plpgsql
AS $$
DECLARE
result INT = 0;
temp INT;
rec RECORD;
current_block_time BIGINT = (SELECT MAX(block_time) FROM contract_readers);
BEGIN
FOR rec IN
WITH templates AS MATERIALIZED (
SELECT DISTINCT template_id, assets_contract
FROM atomicmarket_stats_prices_master
WHERE template_id IS NOT NULL
), sales AS MATERIALIZED (
SELECT assets_contract, SUBSTRING(f FROM 2)::BIGINT template_id, MIN(price) min_price
FROM atomicmarket_sales_filters_listed
JOIN LATERAL UNNEST(filter) u(f) ON u.f LIKE 't%'
WHERE seller_contract IS DISTINCT FROM TRUE
AND asset_count = 1
AND updated_at_time + 0 <= (current_block_time - 3600 * 24 * 3 * 1000) -- only include sales older than 3 days
GROUP BY template_id, assets_contract
)
SELECT template_id, assets_contract, sug.suggested_median, sug.suggested_average
FROM templates
LEFT OUTER JOIN sales USING (template_id, assets_contract)
CROSS JOIN LATERAL (
SELECT
LEAST(PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY price), sales.min_price) suggested_median,
LEAST(AVG(price)::BIGINT, sales.min_price) suggested_average
FROM (
(
SELECT listing_id /* not used, but required to prevent the same price being discarded in the union*/, price
FROM atomicmarket_stats_prices_master
WHERE template_id = templates.template_id AND assets_contract = templates.assets_contract
AND time >= ((extract(epoch from now() - '3 days'::INTERVAL)) * 1000)::BIGINT
)
UNION
(
SELECT listing_id, price
FROM atomicmarket_stats_prices_master
WHERE template_id = templates.template_id AND assets_contract = templates.assets_contract
ORDER BY time DESC
LIMIT 5
)
) prices
) sug
LOOP
INSERT INTO atomicmarket_template_prices AS tp (market_contract, assets_contract, collection_name, template_id, symbol,
median, average, suggested_median, suggested_average, "min", "max", sales)
SELECT
market_contract, assets_contract, collection_name, template_id, symbol,
PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY price) median,
AVG(price)::bigint average,
rec.suggested_median,
rec.suggested_average,
MIN(price) "min", MAX(price) "max", COUNT(*) sales
FROM atomicmarket_stats_prices_master
WHERE template_id = rec.template_id AND assets_contract = rec.assets_contract
GROUP BY market_contract, assets_contract, collection_name, template_id, symbol
ON CONFLICT (market_contract, assets_contract, collection_name, template_id, symbol)
DO UPDATE SET
median = EXCLUDED.median,
average = EXCLUDED.average,
suggested_median = EXCLUDED.suggested_median,
suggested_average = EXCLUDED.suggested_average,
"min" = EXCLUDED."min",
"max" = EXCLUDED."max",
sales = EXCLUDED.sales
WHERE tp.median IS DISTINCT FROM EXCLUDED.median
OR tp.average IS DISTINCT FROM EXCLUDED.average
OR tp.suggested_median IS DISTINCT FROM EXCLUDED.suggested_median
OR tp."min" IS DISTINCT FROM EXCLUDED."min"
OR tp."max" IS DISTINCT FROM EXCLUDED."max"
OR tp.sales IS DISTINCT FROM EXCLUDED.sales
;

GET DIAGNOSTICS temp = ROW_COUNT;
result = result + temp;
END LOOP;

IF (random() <= 0.05) -- occasionally, remove deleted templates
THEN
DELETE FROM atomicmarket_template_prices
WHERE (template_id, assets_contract) NOT IN (
SELECT DISTINCT template_id, assets_contract
FROM atomicmarket_stats_prices_master
WHERE template_id IS NOT NULL
);
GET DIAGNOSTICS temp = ROW_COUNT;
result = result + temp;
END IF;

RETURN result;
END
$$;

SELECT update_atomicmarket_template_prices();

create index atomicmarket_template_prices_collection_name on atomicmarket_template_prices (collection_name);
create index atomicmarket_template_prices_template_id on atomicmarket_template_prices (template_id);

1 change: 1 addition & 0 deletions definitions/migrations/1.3.14/database.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
UPDATE dbinfo SET "value" = '1.3.14' WHERE name = 'version';
2 changes: 1 addition & 1 deletion definitions/tables/atomicmarket_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,4 @@ CREATE INDEX atomicmarket_stats_markets_price ON atomicmarket_stats_markets USIN
CREATE INDEX atomicmarket_stats_markets_time ON atomicmarket_stats_markets USING btree ("time");
CREATE INDEX atomicmarket_stats_markets_asset_id ON atomicmarket_stats_markets USING btree ("asset_id");
CREATE INDEX atomicmarket_stats_markets_schema_name ON atomicmarket_stats_markets USING btree ("schema_name");
CREATE INDEX atomicmarket_stats_markets_template_id ON atomicmarket_stats_markets USING btree ("template_id");
CREATE INDEX atomicmarket_stats_markets_template_id_time ON atomicmarket_stats_markets (template_id, time);
15 changes: 0 additions & 15 deletions definitions/views/atomicmarket_template_prices_master.sql

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eosio-contract-api",
"version": "1.3.13",
"version": "1.3.14",
"description": "EOSIO Contract API",
"author": "pink.gg",
"license": "AGPL-3.0",
Expand Down
8 changes: 4 additions & 4 deletions src/api/namespaces/atomicmarket/handlers/assets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('AtomicMarket Assets API', () => {
template_id: template_id2,
});

await client.query('REFRESH MATERIALIZED VIEW atomicmarket_template_prices');
await client.refreshTemplatePrices();

expect(await getAssetIds({sort: 'suggested_median_price', asset_id: `${asset_id1},${asset_id2}`}))
.to.deep.equal([asset_id1, asset_id2]);
Expand Down Expand Up @@ -69,7 +69,7 @@ describe('AtomicMarket Assets API', () => {
template_id: template_id2,
});

await client.query('REFRESH MATERIALIZED VIEW atomicmarket_template_prices');
await client.refreshTemplatePrices();

expect(await getAssetIds({sort: 'suggested_average_price', asset_id: `${asset_id1},${asset_id2}`}))
.to.deep.equal([asset_id1, asset_id2]);
Expand Down Expand Up @@ -97,7 +97,7 @@ describe('AtomicMarket Assets API', () => {
template_id: template_id2,
});

await client.query('REFRESH MATERIALIZED VIEW atomicmarket_template_prices');
await client.refreshTemplatePrices();

expect(await getAssetIds({sort: 'median_price', asset_id: `${asset_id1},${asset_id2}`}))
.to.deep.equal([asset_id1, asset_id2]);
Expand Down Expand Up @@ -125,7 +125,7 @@ describe('AtomicMarket Assets API', () => {
template_id: template_id2,
});

await client.query('REFRESH MATERIALIZED VIEW atomicmarket_template_prices');
await client.refreshTemplatePrices();

expect(await getAssetIds({sort: 'average_price', asset_id: `${asset_id1},${asset_id2}`}))
.to.deep.equal([asset_id1, asset_id2]);
Expand Down
4 changes: 3 additions & 1 deletion src/api/namespaces/atomicmarket/handlers/prices.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ describe('AtomicMarket Prices API', () => {
});

txit('has data', async () => {
await client.createContractReader();

const account = 'account1234';
const token = await client.createToken({token_symbol: 'SYM'});
const token2 = await client.createToken({token_symbol: 'WAX'});
Expand Down Expand Up @@ -145,7 +147,7 @@ describe('AtomicMarket Prices API', () => {
buyoffer_id: buyOffer6.buyoffer_id,
asset_id: asset6.asset_id
});
await client.refreshPrice();
await client.refreshTemplatePrices();

const response = await getUsersInventoryPrices({}, getTestContext(client, {account}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const {client, txit} = initAtomicMarketTest();
async function getSalesIds(values: RequestValues): Promise<Array<number>> {
const testContext = getTestContext(client);

await client.query('SELECT update_atomicmarket_sales_filters()');
await client.refreshSalesFilters();

const result = await getSalesTemplatesV2Action({
symbol: 'TEST',
Expand Down Expand Up @@ -404,7 +404,7 @@ describe('AtomicMarket Sales API', () => {
const {offer_id} = await client.createOfferAsset({}, {template_id});
const {sale_id} = await client.createSale({offer_id});

await client.query('SELECT update_atomicmarket_sales_filters()');
await client.refreshSalesFilters();

const testContext = getTestContext(client);

Expand Down
8 changes: 4 additions & 4 deletions src/api/namespaces/atomicmarket/handlers/sales2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ async function getSalesIds(values: RequestValues, options = {refresh: true}): Pr
const testContext = getTestContext(client);

if (options.refresh) {
await client.query('SELECT update_atomicmarket_sales_filters()');
await client.refreshSalesFilters();
}

const result = await getSalesV2Action(values, testContext);
Expand Down Expand Up @@ -69,7 +69,7 @@ describe('AtomicMarket Sales API', () => {
state: SaleState.LISTED,
});

await client.query('SELECT update_atomicmarket_sales_filters()');
await client.refreshSalesFilters();

await client.query(`UPDATE atomicmarket_sales SET state = ${SaleState.SOLD} WHERE sale_id = $1`, [sale_id2]);

Expand Down Expand Up @@ -680,7 +680,7 @@ describe('AtomicMarket Sales API', () => {

const testContext = getTestContext(client);

await client.query('SELECT update_atomicmarket_sales_filters()');
await client.refreshSalesFilters();

const result = await getSalesV2Action({ids: `${sale_id}`, count: 'true'}, testContext);

Expand Down Expand Up @@ -768,7 +768,7 @@ describe('AtomicMarket Sales API', () => {

const testContext = getTestContext(client);

await client.query('SELECT update_atomicmarket_sales_filters()');
await client.refreshSalesFilters();

const [result] = await getSalesV2Action({}, testContext);

Expand Down
13 changes: 12 additions & 1 deletion src/api/namespaces/atomicmarket/handlers/stats.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const {client, txit} = initAtomicMarketTest();
describe('AtomicMarket Stats API', () => {
describe('getTemplateStatsAction', () => {
txit('gets the templates sales and volume', async () => {
await client.createContractReader();

await client.createToken({token_symbol: 'TOKEN1'});
const {template_id} = await client.createTemplate();
const {template_id: templateId2} = await client.createTemplate();
Expand All @@ -36,7 +38,6 @@ describe('AtomicMarket Stats API', () => {

const response = await getTemplateStatsAction({symbol: 'TOKEN1'}, context);


expect(response.results.length).to.equal(2);
expect(response.results.find((r: any) => r.template.template_id === template_id)).to.deep.contains({
volume: '2',
Expand All @@ -51,6 +52,8 @@ describe('AtomicMarket Stats API', () => {

context('with template_id filter', () => {
txit('gets the templates sales and volume even if they dont have sales', async () => {
await client.createContractReader();

await client.createToken({token_symbol: 'TOKEN1'});
const context = getTestContext(client);
// Included
Expand All @@ -73,6 +76,8 @@ describe('AtomicMarket Stats API', () => {

context('with schema_name filter', () => {
txit('gets the templates sales and volume even if they dont have sales', async () => {
await client.createContractReader();

await client.createToken({token_symbol: 'TOKEN1'});
const context = getTestContext(client);
// Included
Expand All @@ -96,6 +101,8 @@ describe('AtomicMarket Stats API', () => {

context('with collection_name filter', () => {
txit('gets the templates sales and volume even if they dont have sales', async () => {
await client.createContractReader();

await client.createToken({token_symbol: 'TOKEN1'});
const context = getTestContext(client);
// Included
Expand All @@ -119,6 +126,8 @@ describe('AtomicMarket Stats API', () => {

context('with search filter', () => {
txit('gets the templates sales and volume even if they dont have sales', async () => {
await client.createContractReader();

await client.createToken({token_symbol: 'TOKEN1'});
const context = getTestContext(client);
// Included
Expand All @@ -141,6 +150,8 @@ describe('AtomicMarket Stats API', () => {

context('with time after and before filter', () => {
txit('gets the templates sales and volume even if they dont have sales in the period defined', async () => {
await client.createContractReader();

await client.createToken({token_symbol: 'TOKEN1'});
// Included
const {template_id} = await client.createTemplate();
Expand Down
10 changes: 8 additions & 2 deletions src/api/namespaces/atomicmarket/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,22 @@ export class AtomicMarketTestClient extends AtomicAssetsTestClient {
});
}

async refreshPrice(): Promise<void> {
async refreshTemplatePrices(): Promise<void> {
await this.refreshSalesFilters();

await this.refreshStatsMarket();

await this.query('REFRESH MATERIALIZED VIEW atomicmarket_template_prices');
await this.query('SELECT update_atomicmarket_template_prices()');
}

async refreshStatsMarket(): Promise<void> {
await this.query('SELECT update_atomicmarket_stats_market()');
}

async refreshSalesFilters(): Promise<void> {
await this.query('SELECT update_atomicmarket_sales_filters()');
}

async createBuyOffer(values: Record<string, any> = {}): Promise<Record<string, any>> {
return this.insert('atomicmarket_buyoffers', {
market_contract: 'amtest',
Expand Down
Loading

0 comments on commit f2c7ad3

Please sign in to comment.