Skip to content

Commit

Permalink
Move query file logic to structs
Browse files Browse the repository at this point in the history
  • Loading branch information
pawurb committed Jan 25, 2024
1 parent 2658696 commit 08c61a4
Show file tree
Hide file tree
Showing 36 changed files with 218 additions and 149 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,14 @@ The same as `cache_hit` with each table's cache hit info displayed seperately.
### `db_settings`

```rust
struct DbSetting {
struct DbSettings {
name: String,
setting: String,
unit: String,
short_desc: String,
}

db_settings() -> Result<Vec<DbSetting>, PgExtrasError>
db_settings() -> Result<Vec<DbSettings>, PgExtrasError>

name | setting | unit |
------------------------------+---------+------+
Expand Down
150 changes: 38 additions & 112 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub use structs::buffercache_usage::BuffercacheUsage;
pub use structs::cache_hit::CacheHit;
pub use structs::calls::Calls;
pub use structs::connections::Connections;
pub use structs::db_settings::DbSetting;
pub use structs::db_settings::DbSettings;
pub use structs::duplicate_indexes::DuplicateIndexes;
pub use structs::extensions::Extensions;
pub use structs::index_cache_hit::IndexCacheHit;
Expand All @@ -24,7 +24,7 @@ pub use structs::null_indexes::NullIndexes;
pub use structs::outliers::Outliers;
pub use structs::records_rank::RecordsRank;
pub use structs::seq_scans::SeqScans;
pub use structs::shared::{get_default_schema, Tabular};
pub use structs::shared::{get_default_schema, Query, Tabular};
pub use structs::ssl_used::SslUsed;
pub use structs::table_cache_hit::TableCacheHit;
pub use structs::table_index_scans::TableIndexScans;
Expand Down Expand Up @@ -52,117 +52,118 @@ pub fn render_table<T: Tabular>(items: Vec<T>) {
}

pub async fn bloat() -> Result<Vec<Bloat>, PgExtrasError> {
let query = Query::read_file(Query::Bloat);
let query = Query::read_file(Bloat::FILE_NAME);
get_rows(query).await
}

pub async fn blocking(limit: Option<String>) -> Result<Vec<Blocking>, PgExtrasError> {
let limit = limit.unwrap_or("10".to_string());
let query = Query::read_file(Query::Blocking).replace("%{limit}", limit.as_str());
let query = Query::read_file(Blocking::FILE_NAME).replace("%{limit}", limit.as_str());
get_rows(&query).await
}

pub async fn calls(limit: Option<String>) -> Result<Vec<Calls>, PgExtrasError> {
let limit = limit.unwrap_or("10".to_string());
let query = Query::read_file(Query::Calls).replace("%{limit}", limit.as_str());
let query = Query::read_file(Calls::FILE_NAME).replace("%{limit}", limit.as_str());
get_rows(&query).await
}

pub async fn extensions() -> Result<Vec<Extensions>, PgExtrasError> {
let query = Query::read_file(Query::Extensions);
let query = Query::read_file(Extensions::FILE_NAME);
get_rows(query).await
}

pub async fn table_cache_hit() -> Result<Vec<TableCacheHit>, PgExtrasError> {
let query = Query::read_file(Query::TableCacheHit);
let query = Query::read_file(TableCacheHit::FILE_NAME);
get_rows(query).await
}

pub async fn tables(schema: Option<String>) -> Result<Vec<Tables>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::Tables).replace("%{schema}", &schema_name);
let query = Query::read_file(Tables::FILE_NAME).replace("%{schema}", &schema_name);
get_rows(&query).await
}

pub async fn index_cache_hit(schema: Option<String>) -> Result<Vec<IndexCacheHit>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::IndexCacheHit).replace("%{schema}", &schema_name);
let query = Query::read_file(IndexCacheHit::FILE_NAME).replace("%{schema}", &schema_name);
get_rows(&query).await
}

pub async fn indexes() -> Result<Vec<Indexes>, PgExtrasError> {
let query = Query::read_file(Query::Indexes);
let query = Query::read_file(Indexes::FILE_NAME);
get_rows(query).await
}

pub async fn index_size() -> Result<Vec<IndexSize>, PgExtrasError> {
let query = Query::read_file(Query::IndexSize);
let query = Query::read_file(IndexSize::FILE_NAME);
get_rows(query).await
}

pub async fn index_usage(schema: Option<String>) -> Result<Vec<IndexUsage>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::IndexUsage).replace("%{schema}", &schema_name);
let query = Query::read_file(IndexUsage::FILE_NAME).replace("%{schema}", &schema_name);
get_rows(&query).await
}

pub async fn index_scans(schema: Option<String>) -> Result<Vec<IndexScans>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::IndexScans).replace("%{schema}", &schema_name);
let query = Query::read_file(IndexScans::FILE_NAME).replace("%{schema}", &schema_name);
get_rows(&query).await
}

pub async fn null_indexes(
min_relation_size_mb: Option<String>,
) -> Result<Vec<NullIndexes>, PgExtrasError> {
let min_relation_size_mb = min_relation_size_mb.unwrap_or("0".to_string());
let query = Query::read_file(Query::NullIndexes)
let query = Query::read_file(NullIndexes::FILE_NAME)
.replace("%{min_relation_size_mb}", &min_relation_size_mb);
get_rows(&query).await
}

pub async fn locks() -> Result<Vec<Locks>, PgExtrasError> {
let query = Query::read_file(Query::Locks);
let query = Query::read_file(Locks::FILE_NAME);
get_rows(query).await
}

pub async fn all_locks() -> Result<Vec<AllLocks>, PgExtrasError> {
let query = Query::read_file(Query::AllLocks);
let query = Query::read_file(AllLocks::FILE_NAME);
get_rows(query).await
}

pub async fn long_running_queries() -> Result<Vec<LongRunningQueries>, PgExtrasError> {
let query = Query::read_file(Query::LongRunningQueries);
let query = Query::read_file(LongRunningQueries::FILE_NAME);
get_rows(query).await
}

pub async fn mandelbrot() -> Result<Vec<Mandelbrot>, PgExtrasError> {
let query = Query::read_file(Query::Mandelbrot);
let query = Query::read_file(Mandelbrot::FILE_NAME);
get_rows(query).await
}

pub async fn outliers() -> Result<Vec<Outliers>, PgExtrasError> {
let query = Query::read_file(Query::Outliers);
let query = Query::read_file(Outliers::FILE_NAME);
get_rows(query).await
}

pub async fn records_rank(schema: Option<String>) -> Result<Vec<RecordsRank>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::RecordsRank).replace("%{schema}", schema_name.as_str());
let query = Query::read_file(RecordsRank::FILE_NAME).replace("%{schema}", schema_name.as_str());
get_rows(&query).await
}

pub async fn seq_scans(schema: Option<String>) -> Result<Vec<SeqScans>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::SeqScans).replace("%{schema}", schema_name.as_str());
let query = Query::read_file(SeqScans::FILE_NAME).replace("%{schema}", schema_name.as_str());
get_rows(&query).await
}

pub async fn table_index_scans(
schema: Option<String>,
) -> Result<Vec<TableIndexScans>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::TableIndexScans).replace("%{schema}", schema_name.as_str());
let query =
Query::read_file(TableIndexScans::FILE_NAME).replace("%{schema}", schema_name.as_str());
get_rows(&query).await
}

Expand All @@ -171,148 +172,73 @@ pub async fn table_indexes_size(
) -> Result<Vec<TableIndexesSize>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query =
Query::read_file(Query::TableIndexesSize).replace("%{schema}", schema_name.as_str());
Query::read_file(TableIndexesSize::FILE_NAME).replace("%{schema}", schema_name.as_str());
get_rows(&query).await
}

pub async fn table_size() -> Result<Vec<TableSize>, PgExtrasError> {
let query = Query::read_file(Query::TableSize);
let query = Query::read_file(TableSize::FILE_NAME);
get_rows(query).await
}

pub async fn total_index_size() -> Result<Vec<TotalIndexSize>, PgExtrasError> {
let query = Query::read_file(Query::TotalIndexSize);
let query = Query::read_file(TotalIndexSize::FILE_NAME);
get_rows(query).await
}

pub async fn total_table_size() -> Result<Vec<TotalTableSize>, PgExtrasError> {
let query = Query::read_file(Query::TotalTableSize);
let query = Query::read_file(TotalTableSize::FILE_NAME);
get_rows(query).await
}

pub async fn unused_indexes(schema: Option<String>) -> Result<Vec<UnusedIndexes>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::UnusedIndexes).replace("%{schema}", schema_name.as_str());
let query =
Query::read_file(UnusedIndexes::FILE_NAME).replace("%{schema}", schema_name.as_str());
get_rows(&query).await
}

pub async fn duplicate_indexes() -> Result<Vec<DuplicateIndexes>, PgExtrasError> {
let query = Query::read_file(Query::DuplicateIndexes);
let query = Query::read_file(DuplicateIndexes::FILE_NAME);
get_rows(query).await
}

pub async fn vacuum_stats() -> Result<Vec<VacuumStats>, PgExtrasError> {
let query = Query::read_file(Query::VacuumStats);
let query = Query::read_file(VacuumStats::FILE_NAME);
get_rows(query).await
}

pub async fn buffercache_stats() -> Result<Vec<BuffercacheStats>, PgExtrasError> {
let query = Query::read_file(Query::BuffercacheStats);
let query = Query::read_file(BuffercacheStats::FILE_NAME);
get_rows(query).await
}

pub async fn buffercache_usage() -> Result<Vec<BuffercacheUsage>, PgExtrasError> {
let query = Query::read_file(Query::BuffercacheUsage);
let query = Query::read_file(BuffercacheUsage::FILE_NAME);
get_rows(query).await
}

pub async fn ssl_used() -> Result<Vec<SslUsed>, PgExtrasError> {
let query = Query::read_file(Query::SslUsed);
let query = Query::read_file(SslUsed::FILE_NAME);
get_rows(query).await
}

pub async fn connections() -> Result<Vec<Connections>, PgExtrasError> {
let query = Query::read_file(Query::Connections);
let query = Query::read_file(Connections::FILE_NAME);
get_rows(query).await
}

pub async fn cache_hit(schema: Option<String>) -> Result<Vec<CacheHit>, PgExtrasError> {
let schema_name = schema.unwrap_or(get_default_schema());
let query = Query::read_file(Query::CacheHit).replace("%{schema}", schema_name.as_str());
let query = Query::read_file(CacheHit::FILE_NAME).replace("%{schema}", schema_name.as_str());
get_rows(&query).await
}

pub async fn db_settings() -> Result<Vec<DbSetting>, PgExtrasError> {
let query = Query::read_file(Query::DbSettings);
pub async fn db_settings() -> Result<Vec<DbSettings>, PgExtrasError> {
let query = Query::read_file(DbSettings::FILE_NAME);
get_rows(query).await
}

enum Query {
CacheHit,
Bloat,
Blocking,
Calls,
Extensions,
TableCacheHit,
Tables,
IndexCacheHit,
DbSettings,
Indexes,
IndexSize,
IndexUsage,
IndexScans,
NullIndexes,
Locks,
AllLocks,
LongRunningQueries,
Mandelbrot,
Outliers,
RecordsRank,
SeqScans,
TableIndexScans,
TableIndexesSize,
TableSize,
TotalIndexSize,
TotalTableSize,
UnusedIndexes,
DuplicateIndexes,
VacuumStats,
BuffercacheStats,
BuffercacheUsage,
SslUsed,
Connections,
}

impl Query {
pub fn read_file(query: Query) -> &'static str {
match query {
Query::CacheHit => include_str!("queries/cache_hit.sql"),
Query::DbSettings => include_str!("queries/db_settings.sql"),
Query::BuffercacheStats => include_str!("queries/buffercache_stats.sql"),
Query::BuffercacheUsage => include_str!("queries/buffercache_usage.sql"),
Query::SslUsed => include_str!("queries/ssl_used.sql"),
Query::Connections => include_str!("queries/connections.sql"),
Query::Bloat => include_str!("queries/bloat.sql"),
Query::Blocking => include_str!("queries/blocking.sql"),
Query::Calls => include_str!("queries/calls.sql"),
Query::Extensions => include_str!("queries/extensions.sql"),
Query::TableCacheHit => include_str!("queries/table_cache_hit.sql"),
Query::Tables => include_str!("queries/tables.sql"),
Query::IndexCacheHit => include_str!("queries/index_cache_hit.sql"),
Query::Indexes => include_str!("queries/indexes.sql"),
Query::IndexSize => include_str!("queries/index_size.sql"),
Query::IndexUsage => include_str!("queries/index_usage.sql"),
Query::IndexScans => include_str!("queries/index_scans.sql"),
Query::NullIndexes => include_str!("queries/null_indexes.sql"),
Query::Locks => include_str!("queries/locks.sql"),
Query::AllLocks => include_str!("queries/all_locks.sql"),
Query::LongRunningQueries => include_str!("queries/long_running_queries.sql"),
Query::Mandelbrot => include_str!("queries/mandelbrot.sql"),
Query::Outliers => include_str!("queries/outliers.sql"),
Query::RecordsRank => include_str!("queries/records_rank.sql"),
Query::SeqScans => include_str!("queries/seq_scans.sql"),
Query::TableIndexScans => include_str!("queries/table_index_scans.sql"),
Query::TableIndexesSize => include_str!("queries/table_indexes_size.sql"),
Query::TableSize => include_str!("queries/table_size.sql"),
Query::TotalIndexSize => include_str!("queries/total_index_size.sql"),
Query::TotalTableSize => include_str!("queries/total_table_size.sql"),
Query::UnusedIndexes => include_str!("queries/unused_indexes.sql"),
Query::DuplicateIndexes => include_str!("queries/duplicate_indexes.sql"),
Query::VacuumStats => include_str!("queries/vacuum_stats.sql"),
}
}
}

#[derive(Error, Debug)]
#[non_exhaustive]
pub enum PgExtrasError {
Expand Down
4 changes: 3 additions & 1 deletion src/structs/all_locks.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::structs::shared::{get_default_interval, Tabular};
use crate::structs::shared::{get_default_interval, Query, Tabular};
use sqlx::postgres::{types::PgInterval, PgRow};
use sqlx::Row;

Expand All @@ -15,6 +15,8 @@ pub struct AllLocks {
}

impl Tabular for AllLocks {
const FILE_NAME: Query = Query::AllLocks;

fn new(row: &PgRow) -> Self {
Self {
pid: row.try_get("pid").unwrap_or_default(),
Expand Down
4 changes: 3 additions & 1 deletion src/structs/bloat.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::structs::shared::Tabular;
use crate::structs::shared::{Query, Tabular};
use sqlx::postgres::PgRow;
use sqlx::types::BigDecimal;
use sqlx::Row;
Expand All @@ -13,6 +13,8 @@ pub struct Bloat {
}

impl Tabular for Bloat {
const FILE_NAME: Query = Query::Bloat;

fn new(row: &PgRow) -> Self {
Self {
typefield: row.try_get("type").unwrap_or_default(),
Expand Down
4 changes: 3 additions & 1 deletion src/structs/blocking.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::structs::shared::{get_default_interval, Tabular};
use crate::structs::shared::{get_default_interval, Query, Tabular};
use sqlx::postgres::{types::PgInterval, PgRow};
use sqlx::Row;

Expand All @@ -15,6 +15,8 @@ pub struct Blocking {
}

impl Tabular for Blocking {
const FILE_NAME: Query = Query::Blocking;

fn new(row: &PgRow) -> Self {
Self {
blocked_pid: row.try_get("blocked_pid").unwrap_or_default(),
Expand Down
4 changes: 3 additions & 1 deletion src/structs/buffercache_stats.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::structs::shared::Tabular;
use crate::structs::shared::{Query, Tabular};
use sqlx::postgres::PgRow;
use sqlx::Row;

Expand All @@ -11,6 +11,8 @@ pub struct BuffercacheStats {
}

impl Tabular for BuffercacheStats {
const FILE_NAME: Query = Query::BuffercacheStats;

fn new(row: &PgRow) -> Self {
Self {
relname: row.try_get("relname").unwrap_or_default(),
Expand Down
Loading

0 comments on commit 08c61a4

Please sign in to comment.