@softvisio/core
Version:
Softisio core
213 lines (182 loc) • 5.04 kB
JavaScript
import sql from "#lib/sql";
const STATS_PERIODS = {
"7 days": "hour",
"3 months": "day",
"1 year": "day",
};
const SQL = {
"createLink": sql`
INSERT INTO
telegram_bot_link
(
telegram_bot_id,
name,
description
)
VALUES ( ?, ?, ? )
RETURNING
id,
name,
description
`,
"updateLink": sql`
UPDATE
telegram_bot_link
SET
name = coalesce( ?, name ),
description = coalesce( ?, description )
WHERE
id = ?
AND telegram_bot_id = ?
`,
"deleteLink": sql`DELETE FROM telegram_bot_link WHERE id = ? AND telegram_bot_id = ?`.prepare(),
"getLinkStats": sql`WITH params AS (
WITH args AS ( SELECT ?::interval AS interval, ?::text AS step ),
step_interval AS ( SELECT ( '1 ' || ( SELECT step FROM args ) )::interval AS interval )
SELECT
( SELECT step FROM args ) AS step,
( SELECT interval FROM step_interval ) AS step_interval,
( date_trunc( ( SELECT step FROM args ), CURRENT_TIMESTAMP ) - ( SELECT interval FROM args ) + ( SELECT interval FROM step_interval ) ) AS start,
date_trunc( ( SELECT step FROM args ), CURRENT_TIMESTAMP ) AS end
),
series AS (
SELECT date FROM generate_series(
( SELECT start FROM params ),
( SELECT "end" FROM params ),
( SELECT step_interval FROM params )
) AS date
),
stats AS (
SELECT
date_trunc( ( SELECT step FROM params ), date ) AS truncated_date,
max( total_subscribed_users ) AS total_subscribed_users,
max( total_unsubscribed_users ) AS total_unsubscribed_users,
sum( total_subscribed_users_delta )::int4 AS total_subscribed_users_delta,
sum( total_unsubscribed_users_delta )::int4 AS total_unsubscribed_users_delta
FROM
telegram_bot_link_stats
WHERE
telegram_bot_link_id = ?
AND date >= ( SELECT start FROM params )
GROUP BY
truncated_date
),
start AS (
SELECT
( SELECT start FROM params ) AS date,
total_subscribed_users,
total_unsubscribed_users
FROM
telegram_bot_link_stats
WHERE
telegram_bot_link_id = ?
AND date <= ( SELECT start FROM params )
ORDER BY
telegram_bot_link_stats.date DESC
LIMIT 1
),
"end" AS (
SELECT
( SELECT "end" FROM params ) AS date,
total_subscribed_users,
total_unsubscribed_users
FROM
telegram_bot_link
WHERE
id = ?
)
SELECT
series.date,
coalesce(
"end".total_subscribed_users,
stats.total_subscribed_users,
start.total_subscribed_users
) AS total_subscribed_users,
0 - coalesce(
"end".total_unsubscribed_users,
stats.total_unsubscribed_users,
start.total_unsubscribed_users
) AS total_unsubscribed_users,
CASE
WHEN total_subscribed_users_delta > 0 THEN total_subscribed_users_delta
ELSE 0
END AS total_subscribed_users_delta,
CASE
WHEN total_unsubscribed_users_delta > 0 THEN 0 - total_unsubscribed_users_delta
ELSE 0
END AS total_unsubscribed_users_delta
FROM
series
LEFT JOIN stats ON ( series.date = stats.truncated_date )
LEFT JOIN start ON ( series.date = start.date )
LEFT JOIN "end" ON ( series.date = "end".date )
`.prepare(),
"registerUser": sql`
INSERT INTO
telegram_bot_user_link
(
telegram_bot_id,
telegram_user_id,
telegram_bot_link_id,
new_user
)
VALUES ( ?, ?, ?, ? )
ON CONFLICT DO NOTHING
`.prepare(),
};
export default class {
constructor ( bot ) {
this.
}
// properties
get bot () {
return this.
}
get dbh () {
return this.
}
// public
async createLink ( { name, description, dbh } = {} ) {
dbh ||= this.dbh;
return dbh.selectRow( SQL.createLink, [
//
this.bot.id,
name || new Date(),
description,
] );
}
async updateLink ( linkId, { name, description, dbh } = {} ) {
dbh ||= this.dbh;
const res = await dbh.do( SQL.updateLink, [ name, description, linkId, this.bot.id ] );
if ( !res.ok ) return res;
if ( !res.meta.rows ) return result( 404 );
return res;
}
async deleteLink ( linkId, { dbh } = {} ) {
dbh ||= this.sbh;
const res = await dbh.do( SQL.delete, [ linkId, this.bot.id ] );
if ( !res.ok ) return res;
if ( !res.meta.rows ) return result( 404 );
return res;
}
async getLinkStats ( linkId, period ) {
return this.dbh.select( SQL.getLinkStats, [
//
period,
STATS_PERIODS[ period ],
linkId,
linkId,
linkId,
] );
}
async registerUser ( linkId, userId, isNewUser ) {
return this.dbh.do( SQL.registerUser, [
//
this.bot.id,
userId,
linkId,
isNewUser,
] );
}
}