Skip to content

Commit

Permalink
Add check "Do not index booleans" (#377)
Browse files Browse the repository at this point in the history
* Add IndexWithColumns to the model and a new check INDEXES_WITH_BOOLEAN

* Fix checkstyle

* Add tests
  • Loading branch information
mfvanek authored Apr 28, 2024
1 parent ff4de6f commit a530341
Show file tree
Hide file tree
Showing 23 changed files with 628 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ public class Column implements DbObject, ColumnNameAware, Comparable<Column> {
private final String columnName;
private final boolean notNull;

/**
* Constructs a {@code Column} object.
*
* @param tableName table name; should be non-blank.
* @param columnName column name; should be non-blank.
* @param notNull whether column is not null or nullable
*/
protected Column(@Nonnull final String tableName,
@Nonnull final String columnName,
final boolean notNull) {
Expand Down Expand Up @@ -126,11 +133,25 @@ public int compareTo(@Nonnull final Column other) {
return Boolean.compare(notNull, other.notNull);
}

/**
* Constructs a not null {@code Column} object.
*
* @param tableName table name; should be non-blank.
* @param columnName column name; should be non-blank.
* @return {@code Column}
*/
@Nonnull
public static Column ofNotNull(@Nonnull final String tableName, @Nonnull final String columnName) {
return new Column(tableName, columnName, true);
}

/**
* Constructs a nullable {@code Column} object.
*
* @param tableName table name; should be non-blank.
* @param columnName column name; should be non-blank.
* @return {@code Column}
*/
@Nonnull
public static Column ofNullable(@Nonnull final String tableName, @Nonnull final String columnName) {
return new Column(tableName, columnName, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* @since 0.6.2
*/
@Immutable
public class ColumnWithSerialType implements DbObject, ColumnNameAware, Comparable<ColumnWithSerialType> {
public final class ColumnWithSerialType implements DbObject, ColumnNameAware, Comparable<ColumnWithSerialType> {

private final Column column;
private final SerialType serialType;
Expand All @@ -44,7 +44,7 @@ private ColumnWithSerialType(@Nonnull final Column column,
*/
@Nonnull
@Override
public final String getName() {
public String getName() {
return column.getName();
}

Expand Down Expand Up @@ -110,7 +110,7 @@ public String toString() {
* {@inheritDoc}
*/
@Override
public final boolean equals(final Object other) {
public boolean equals(final Object other) {
if (this == other) {
return true;
}
Expand All @@ -129,7 +129,7 @@ public final boolean equals(final Object other) {
* {@inheritDoc}
*/
@Override
public final int hashCode() {
public int hashCode() {
return Objects.hash(column, serialType, sequenceName);
}

Expand All @@ -148,25 +148,54 @@ public int compareTo(@Nonnull final ColumnWithSerialType other) {
return sequenceName.compareTo(other.sequenceName);
}

/**
* Constructs a {@code ColumnWithSerialType} object of given serial type.
*
* @param column column; should be non-null.
* @param serialType column serial type; should be non-null.
* @param sequenceName sequence name; should be non-blank.
* @return {@code ColumnWithSerialType}
*/
@Nonnull
public static ColumnWithSerialType of(@Nonnull final Column column,
@Nonnull final SerialType serialType,
@Nonnull final String sequenceName) {
return new ColumnWithSerialType(column, serialType, sequenceName);
}

/**
* Constructs a {@code ColumnWithSerialType} object of {@code bigserial} type.
*
* @param column column; should be non-null.
* @param sequenceName sequence name; should be non-blank.
* @return {@code ColumnWithSerialType}
*/
@Nonnull
public static ColumnWithSerialType ofBigSerial(@Nonnull final Column column,
@Nonnull final String sequenceName) {
return of(column, SerialType.BIG_SERIAL, sequenceName);
}

/**
* Constructs a {@code ColumnWithSerialType} object of {@code serial} type.
*
* @param column column; should be non-null.
* @param sequenceName sequence name; should be non-blank.
* @return {@code ColumnWithSerialType}
*/
@Nonnull
public static ColumnWithSerialType ofSerial(@Nonnull final Column column,
@Nonnull final String sequenceName) {
return of(column, SerialType.SERIAL, sequenceName);
}

/**
* Constructs a {@code ColumnWithSerialType} object of {@code smallserial} type.
*
* @param column column; should be non-null.
* @param sequenceName sequence name; should be non-blank.
* @return {@code ColumnWithSerialType}
*/
@Nonnull
public static ColumnWithSerialType ofSmallSerial(@Nonnull final Column column,
@Nonnull final String sequenceName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,13 @@ public String toString() {
return Index.class.getSimpleName() + '{' + innerToString() + '}';
}

/**
* An auxiliary utility method for implementing {@code toString()} in child classes.
*
* @return string representation of the internal fields of this class
*/
@SuppressWarnings("WeakerAccess")
@Nonnull
protected String innerToString() {
return "tableName='" + tableName + '\'' +
", indexName='" + indexName + '\'';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public int getBloatPercentage() {
return bloatPercentage;
}

/**
* {@inheritDoc}
*/
@Nonnull
@Override
protected String innerToString() {
return super.innerToString() + ", bloatSizeInBytes=" + bloatSizeInBytes +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2019-2024. Ivan Vakhrushev and others.
* https://github.com/mfvanek/pg-index-health
*
* This file is a part of "pg-index-health" - a Java library for
* analyzing and maintaining indexes health in PostgreSQL databases.
*
* Licensed under the Apache License 2.0
*/

package io.github.mfvanek.pg.model.index;

import io.github.mfvanek.pg.model.column.Column;
import io.github.mfvanek.pg.model.validation.Validators;

import java.util.List;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;

/**
* Represents database index with information about size and columns.
*
* @author Ivan Vahrushev
* @since 0.10.4
*/
@Immutable
public class IndexWithColumns extends IndexWithSize {

private final List<Column> columns;

@SuppressWarnings("WeakerAccess")
protected IndexWithColumns(@Nonnull final String tableName,
@Nonnull final String indexName,
final long indexSizeInBytes,
@Nonnull final List<Column> columns) {
super(tableName, indexName, indexSizeInBytes);
final List<Column> defensiveCopy = List.copyOf(Objects.requireNonNull(columns, "columns cannot be null"));
Validators.validateThatTableIsTheSame(tableName, defensiveCopy);
this.columns = defensiveCopy;
}

/**
* Gets columns in index.
*
* @return list of columns
*/
@Nonnull
public List<Column> getColumns() {
return columns;
}

/**
* {@inheritDoc}
*/
@Nonnull
@Override
protected String innerToString() {
return super.innerToString() + ", columns=" + columns;
}

/**
* {@inheritDoc}
*/
@Nonnull
@Override
public String toString() {
return IndexWithColumns.class.getSimpleName() + '{' + innerToString() + '}';
}

/**
* Constructs an {@code IndexWithColumns} object with one column.
*
* @param tableName table name; should be non-blank.
* @param indexName index name; should be non-blank.
* @param indexSizeInBytes index size in bytes; should be positive or zero.
* @param column column in index.
* @return {@code IndexWithColumns}
*/
@Nonnull
public static IndexWithColumns ofSingle(@Nonnull final String tableName,
@Nonnull final String indexName,
final long indexSizeInBytes,
@Nonnull final Column column) {
final List<Column> columns = List.of(Objects.requireNonNull(column, "column cannot be null"));
return new IndexWithColumns(tableName, indexName, indexSizeInBytes, columns);
}

/**
* Constructs an {@code IndexWithColumns} object with given columns.
*
* @param tableName table name; should be non-blank.
* @param indexName index name; should be non-blank.
* @param indexSizeInBytes index size in bytes; should be positive or zero.
* @param columns columns in index.
* @return {@code IndexWithColumns}
*/
@Nonnull
public static IndexWithColumns ofColumns(@Nonnull final String tableName,
@Nonnull final String indexName,
final long indexSizeInBytes,
@Nonnull final List<Column> columns) {
return new IndexWithColumns(tableName, indexName, indexSizeInBytes, columns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,36 @@
package io.github.mfvanek.pg.model.index;

import io.github.mfvanek.pg.model.column.Column;
import io.github.mfvanek.pg.model.validation.Validators;

import java.util.List;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;

/**
* Represents database index with information about size and nullable columns.
*
* @author Ivan Vahrushev
* @since 0.0.1
*/
@Immutable
public final class IndexWithNulls extends IndexWithSize {

private final Column nullableColumn;
public final class IndexWithNulls extends IndexWithColumns {

private IndexWithNulls(@Nonnull final String tableName,
@Nonnull final String indexName,
final long indexSizeInBytes,
@Nonnull final Column nullableColumn) {
super(tableName, indexName, indexSizeInBytes);
Objects.requireNonNull(nullableColumn, "nullableColumn cannot be null");
Validators.validateThatTableIsTheSame(tableName, List.of(nullableColumn));
this.nullableColumn = nullableColumn;
super(tableName, indexName, indexSizeInBytes, List.of(Objects.requireNonNull(nullableColumn, "nullableColumn cannot be null")));
}

/**
* Gets nullable column in index.
*
* @return nullable column
*/
@Nonnull
public Column getNullableColumn() {
return nullableColumn;
return getColumns().get(0);
}

/**
Expand All @@ -44,11 +49,19 @@ public Column getNullableColumn() {
@Nonnull
@Override
public String toString() {
return IndexWithNulls.class.getSimpleName() + '{' +
innerToString() +
", nullableColumn=" + nullableColumn + '}';
return IndexWithNulls.class.getSimpleName() + '{' + innerToString() + '}';
}

/**
* Constructs an {@code IndexWithNulls} object.
*
* @param tableName table name; should be non-blank.
* @param indexName index name; should be non-blank.
* @param indexSizeInBytes index size in bytes; should be positive or zero.
* @param nullableColumnName nullable column in this index.
* @return {@code IndexWithNulls}
*/
@Nonnull
public static IndexWithNulls of(@Nonnull final String tableName,
@Nonnull final String indexName,
final long indexSizeInBytes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;

/**
* Represents database index with information about size.
*
* @author Ivan Vahrushev
* @since 0.0.1
*/
@Immutable
public class IndexWithSize extends Index implements IndexSizeAware {

Expand All @@ -36,6 +42,10 @@ public long getIndexSizeInBytes() {
return indexSizeInBytes;
}

/**
* {@inheritDoc}
*/
@Nonnull
@Override
protected String innerToString() {
return super.innerToString() + ", indexSizeInBytes=" + indexSizeInBytes;
Expand All @@ -50,6 +60,15 @@ public String toString() {
return IndexWithSize.class.getSimpleName() + '{' + innerToString() + '}';
}

/**
* Constructs an {@code IndexWithSize} object.
*
* @param tableName table name; should be non-blank.
* @param indexName index name; should be non-blank.
* @param indexSizeInBytes index size in bytes; should be positive or zero.
* @return {@code IndexWithSize}
*/
@Nonnull
public static IndexWithSize of(@Nonnull final String tableName,
@Nonnull final String indexName,
final long indexSizeInBytes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ public long getTableSizeInBytes() {
return tableSizeInBytes;
}

/**
* An auxiliary utility method for implementing {@code toString()} in child classes.
*
* @return string representation of the internal fields of this class
*/
@Nonnull
final String innerToString() {
return "tableName='" + tableName + '\'' +
", tableSizeInBytes=" + tableSizeInBytes;
Expand Down
Loading

0 comments on commit a530341

Please sign in to comment.