Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ struct AffiliateCodeClickRow {

const AFFILIATE_CODE_CLICKS: &str = {
const USE_AFFILIATE_CODE_ID: &str = "{use_affiliate_code_id: Bool}";
const FILTER_AFFILIATE_CODE_ID: &str =
"{filter_affiliate_code_id: Array(UInt64)}";
const FILTER_AFFILIATE_CODE_ID: &str = "filter_affiliate_code_id";

formatcp!(
"SELECT
"WITH ? AS {FILTER_AFFILIATE_CODE_ID}
SELECT
widthBucket(toUnixTimestamp(recorded), {TIME_RANGE_START}, {TIME_RANGE_END}, {TIME_SLICES}) AS bucket,
if({USE_AFFILIATE_CODE_ID}, affiliate_code_id, 0) AS affiliate_code_id,
COUNT(*) AS clicks
Expand Down Expand Up @@ -85,7 +85,6 @@ pub(crate) async fn fetch(
ClickhouseQueryParams::empty(),
&[("use_affiliate_code_id", uses(F::AffiliateCodeId))],
vec![ClickhouseFilterParam::AffiliateCodeId(
"filter_affiliate_code_id",
&metrics.filter_by.affiliate_code_id,
)],
|_| true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ use crate::{

use super::super::{
ClickhouseFilterParam, QueryClickhouseContext, add_to_time_slice,
condense_country, none_if_empty, none_if_zero_version_id,
normalize_loader_for_project,
none_if_empty, none_if_zero_version_id, normalize_loader_for_project,
passes_country_privacy_floor,
};
use super::{AnalyticsData, Metrics, ProjectAnalytics, ProjectMetrics};

const TIME_RANGE_START: &str = "{time_range_start: UInt64}";
const TIME_RANGE_END: &str = "{time_range_end: UInt64}";
const TIME_SLICES: &str = "{time_slices: UInt64}";
const PROJECT_IDS: &str = "{project_ids: Array(UInt64)}";
const PROJECT_IDS: &str = "project_ids";

/// Fields for [`super::ReturnMetrics::project_downloads`].
#[derive(
Expand Down Expand Up @@ -193,16 +193,24 @@ const DOWNLOADS: &str = {
const USE_REASON: &str = "{use_reason: Bool}";
const USE_GAME_VERSION: &str = "{use_game_version: Bool}";
const USE_LOADER: &str = "{use_loader: Bool}";
const FILTER_DOMAIN: &str = "{filter_domain: Array(String)}";
const FILTER_VERSION_ID: &str = "{filter_version_id: Array(UInt64)}";
const FILTER_DOMAIN: &str = "filter_domain";
const FILTER_VERSION_ID: &str = "filter_version_id";
const FILTER_MONETIZED: &str = "{filter_monetized: UInt8}";
const FILTER_COUNTRY: &str = "{filter_country: Array(String)}";
const FILTER_REASON: &str = "{filter_reason: Array(String)}";
const FILTER_GAME_VERSION: &str = "{filter_game_version: Array(String)}";
const FILTER_LOADER: &str = "{filter_loader: Array(String)}";
const FILTER_COUNTRY: &str = "filter_country";
const FILTER_REASON: &str = "filter_reason";
const FILTER_GAME_VERSION: &str = "filter_game_version";
const FILTER_LOADER: &str = "filter_loader";

formatcp!(
"SELECT
"WITH
? AS {PROJECT_IDS},
? AS {FILTER_DOMAIN},
? AS {FILTER_VERSION_ID},
? AS {FILTER_COUNTRY},
? AS {FILTER_REASON},
? AS {FILTER_GAME_VERSION},
? AS {FILTER_LOADER}
SELECT
widthBucket(toUnixTimestamp(recorded), {TIME_RANGE_START}, {TIME_RANGE_END}, {TIME_SLICES}) AS bucket,
downloads.project_id AS source_project_id,
if({USE_PROJECT_ID}, downloads.project_id, 0) AS project_id,
Expand Down Expand Up @@ -275,39 +283,21 @@ pub(crate) async fn fetch(
.param("time_range_start", cx.req.time_range.start.timestamp())
.param("time_range_end", cx.req.time_range.end.timestamp())
.param("time_slices", cx.time_slices.len())
.param("project_ids", cx.project_ids);
.bind(cx.project_ids);
for (param_name, used) in use_columns {
query = query.param(param_name, used)
}
for filter_param in [
ClickhouseFilterParam::String(
"filter_domain",
&metrics.filter_by.domain,
),
ClickhouseFilterParam::VersionId(
"filter_version_id",
&metrics.filter_by.version_id,
),
ClickhouseFilterParam::String(&metrics.filter_by.domain),
ClickhouseFilterParam::VersionId(&metrics.filter_by.version_id),
ClickhouseFilterParam::Bool(
"filter_monetized",
&metrics.filter_by.monetized,
),
ClickhouseFilterParam::String(
"filter_country",
&metrics.filter_by.country,
),
ClickhouseFilterParam::DownloadReason(
"filter_reason",
&metrics.filter_by.reason,
),
ClickhouseFilterParam::String(
"filter_game_version",
&metrics.filter_by.game_version,
),
ClickhouseFilterParam::String(
"filter_loader",
&metrics.filter_by.loader,
),
ClickhouseFilterParam::String(&metrics.filter_by.country),
ClickhouseFilterParam::DownloadReason(&metrics.filter_by.reason),
ClickhouseFilterParam::String(&metrics.filter_by.game_version),
ClickhouseFilterParam::String(&metrics.filter_by.loader),
] {
query = filter_param.bind(query);
}
Expand Down Expand Up @@ -368,6 +358,13 @@ pub(crate) async fn fetch(
}

for (key, downloads) in buckets {
if !passes_country_privacy_floor(
key.country.is_some() || !metrics.filter_by.country.is_empty(),
downloads,
) {
continue;
}

add_to_time_slice(
cx.time_slices,
key.bucket as usize,
Expand All @@ -380,9 +377,7 @@ pub(crate) async fn fetch(
.version_id
.and_then(none_if_zero_version_id),
monetized: key.monetized,
country: key
.country
.map(|country| condense_country(country, downloads)),
country: key.country,
reason: key.reason,
game_version: key.game_version.and_then(none_if_empty),
loader: key.loader.and_then(none_if_empty),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ use crate::{

use super::super::{
ClickhouseFilterParam, QueryClickhouseContext, add_to_time_slice,
condense_country, none_if_empty, none_if_zero_version_id,
normalize_loader_for_project,
none_if_empty, none_if_zero_version_id, normalize_loader_for_project,
passes_country_privacy_floor,
};
use super::{AnalyticsData, Metrics, ProjectAnalytics, ProjectMetrics};

const TIME_RANGE_START: &str = "{time_range_start: UInt64}";
const TIME_RANGE_END: &str = "{time_range_end: UInt64}";
const TIME_SLICES: &str = "{time_slices: UInt64}";
const PROJECT_IDS: &str = "{project_ids: Array(UInt64)}";
const PROJECT_IDS: &str = "project_ids";

/// Fields for [`super::ReturnMetrics::project_playtime`].
#[derive(
Expand Down Expand Up @@ -96,14 +96,21 @@ const PLAYTIME: &str = {
const USE_LOADER: &str = "{use_loader: Bool}";
const USE_GAME_VERSION: &str = "{use_game_version: Bool}";
const USE_COUNTRY: &str = "{use_country: Bool}";
const PARENT_VERSION_IDS: &str = "{parent_version_ids: Array(UInt64)}";
const FILTER_VERSION_ID: &str = "{filter_version_id: Array(UInt64)}";
const FILTER_LOADER: &str = "{filter_loader: Array(String)}";
const FILTER_GAME_VERSION: &str = "{filter_game_version: Array(String)}";
const FILTER_COUNTRY: &str = "{filter_country: Array(String)}";
const PARENT_VERSION_IDS: &str = "parent_version_ids";
const FILTER_VERSION_ID: &str = "filter_version_id";
const FILTER_LOADER: &str = "filter_loader";
const FILTER_GAME_VERSION: &str = "filter_game_version";
const FILTER_COUNTRY: &str = "filter_country";

formatcp!(
"SELECT
"WITH
? AS {PROJECT_IDS},
? AS {PARENT_VERSION_IDS},
? AS {FILTER_VERSION_ID},
? AS {FILTER_LOADER},
? AS {FILTER_GAME_VERSION},
? AS {FILTER_COUNTRY}
SELECT
bucket,
source_project_id,
if({USE_PROJECT_ID}, source_project_id, 0) AS project_id,
Expand Down Expand Up @@ -194,28 +201,16 @@ pub(crate) async fn fetch(
.param("time_range_start", cx.req.time_range.start.timestamp())
.param("time_range_end", cx.req.time_range.end.timestamp())
.param("time_slices", cx.time_slices.len())
.param("project_ids", cx.project_ids)
.param("parent_version_ids", cx.parent_version_ids);
.bind(cx.project_ids)
.bind(cx.parent_version_ids);
for (param_name, used) in use_columns {
query = query.param(param_name, used)
}
for filter_param in [
ClickhouseFilterParam::VersionId(
"filter_version_id",
&metrics.filter_by.version_id,
),
ClickhouseFilterParam::String(
"filter_loader",
&metrics.filter_by.loader,
),
ClickhouseFilterParam::String(
"filter_game_version",
&metrics.filter_by.game_version,
),
ClickhouseFilterParam::String(
"filter_country",
&metrics.filter_by.country,
),
ClickhouseFilterParam::VersionId(&metrics.filter_by.version_id),
ClickhouseFilterParam::String(&metrics.filter_by.loader),
ClickhouseFilterParam::String(&metrics.filter_by.game_version),
ClickhouseFilterParam::String(&metrics.filter_by.country),
] {
query = filter_param.bind(query);
}
Expand Down Expand Up @@ -261,6 +256,13 @@ pub(crate) async fn fetch(
}

for (key, seconds) in buckets {
if !passes_country_privacy_floor(
key.country.is_some() || !metrics.filter_by.country.is_empty(),
seconds,
) {
continue;
}

add_to_time_slice(
cx.time_slices,
key.bucket as usize,
Expand All @@ -272,9 +274,7 @@ pub(crate) async fn fetch(
.and_then(none_if_zero_version_id),
loader: key.loader.and_then(none_if_empty),
game_version: key.game_version.and_then(none_if_empty),
country: key
.country
.map(|country| condense_country(country, seconds)),
country: key.country,
seconds,
}),
}),
Expand Down
46 changes: 21 additions & 25 deletions apps/labrinth/src/routes/v3/analytics_get/metrics/project_views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use crate::{database::models::DBProjectId, routes::ApiError};

use super::super::{
ClickhouseFilterParam, ClickhouseQueryParams, QueryClickhouseContext,
condense_country, none_if_empty, query_clickhouse,
none_if_empty, passes_country_privacy_floor, query_clickhouse,
};
use super::{AnalyticsData, Metrics, ProjectAnalytics, ProjectMetrics};

const TIME_RANGE_START: &str = "{time_range_start: UInt64}";
const TIME_RANGE_END: &str = "{time_range_end: UInt64}";
const TIME_SLICES: &str = "{time_slices: UInt64}";
const PROJECT_IDS: &str = "{project_ids: Array(UInt64)}";
const PROJECT_IDS: &str = "project_ids";

/// Fields for [`super::ReturnMetrics::project_views`].
#[derive(
Expand Down Expand Up @@ -87,13 +87,18 @@ const VIEWS: &str = {
const USE_SITE_PATH: &str = "{use_site_path: Bool}";
const USE_MONETIZED: &str = "{use_monetized: Bool}";
const USE_COUNTRY: &str = "{use_country: Bool}";
const FILTER_DOMAIN: &str = "{filter_domain: Array(String)}";
const FILTER_SITE_PATH: &str = "{filter_site_path: Array(String)}";
const FILTER_DOMAIN: &str = "filter_domain";
const FILTER_SITE_PATH: &str = "filter_site_path";
const FILTER_MONETIZED: &str = "{filter_monetized: UInt8}";
const FILTER_COUNTRY: &str = "{filter_country: Array(String)}";
const FILTER_COUNTRY: &str = "filter_country";

formatcp!(
"SELECT
"WITH
? AS {PROJECT_IDS},
? AS {FILTER_DOMAIN},
? AS {FILTER_SITE_PATH},
? AS {FILTER_COUNTRY}
SELECT
widthBucket(toUnixTimestamp(recorded), {TIME_RANGE_START}, {TIME_RANGE_END}, {TIME_SLICES}) AS bucket,
if({USE_PROJECT_ID}, project_id, 0) AS project_id,
if({USE_DOMAIN}, domain, '') AS domain,
Expand Down Expand Up @@ -137,31 +142,22 @@ pub(crate) async fn fetch(
("use_country", uses(F::Country)),
],
vec![
ClickhouseFilterParam::String(
"filter_domain",
&metrics.filter_by.domain,
),
ClickhouseFilterParam::String(
"filter_site_path",
&metrics.filter_by.site_path,
),
ClickhouseFilterParam::String(&metrics.filter_by.domain),
ClickhouseFilterParam::String(&metrics.filter_by.site_path),
ClickhouseFilterParam::Bool(
"filter_monetized",
&metrics.filter_by.monetized,
),
ClickhouseFilterParam::String(
"filter_country",
&metrics.filter_by.country,
),
ClickhouseFilterParam::String(&metrics.filter_by.country),
],
|_| true,
|row| {
passes_country_privacy_floor(
uses(F::Country) || !metrics.filter_by.country.is_empty(),
row.views,
)
},
|row| row.bucket,
|row| {
let country = if uses(F::Country) {
Some(condense_country(row.country, row.views))
} else {
None
};
AnalyticsData::Project(ProjectAnalytics {
source_project: row.project_id.into(),
metrics: ProjectMetrics::Views(ProjectViews {
Expand All @@ -172,7 +168,7 @@ pub(crate) async fn fetch(
1 => Some(true),
_ => None,
},
country,
country: uses(F::Country).then_some(row.country),
views: row.views,
}),
})
Expand Down
Loading
Loading