github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/views/databases/containers/databaseSummary/index.tsx (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import _ from "lodash";
    12  import React from "react";
    13  
    14  import * as protos from "src/js/protos";
    15  
    16  import { AdminUIState } from "src/redux/state";
    17  import { refreshDatabaseDetails, refreshTableDetails, refreshTableStats, generateTableID, KeyedCachedDataReducerState} from "src/redux/apiReducers";
    18  
    19  import { SortSetting } from "src/views/shared/components/sortabletable";
    20  
    21  import { TableInfo } from "src/views/databases/data/tableInfo";
    22  
    23  // DatabaseSummaryImplicitData describes properties which must be explicitly set
    24  // on a DatabaseSummary component.
    25  export interface DatabaseSummaryExplicitData {
    26    name: string;
    27  }
    28  
    29  // DatabaseSummaryConnectedData describes properties which are applied to a
    30  // DatabaseSummary component by connecting to a redux store.
    31  interface DatabaseSummaryConnectedData {
    32    sortSetting: SortSetting;
    33    tableInfos: TableInfo[];
    34    dbResponse: KeyedCachedDataReducerState<protos.cockroach.server.serverpb.DatabaseDetailsResponse>;
    35    grants: protos.cockroach.server.serverpb.DatabaseDetailsResponse.Grant[];
    36  }
    37  
    38  // DatabaseSummaryActions describes actions which can be dispatched by a
    39  // DatabaseSummary component.
    40  interface DatabaseSummaryActions {
    41    setSort: (setting: SortSetting) => void;
    42    refreshDatabaseDetails: typeof refreshDatabaseDetails;
    43    refreshTableDetails: typeof refreshTableDetails;
    44    refreshTableStats: typeof refreshTableStats;
    45  }
    46  
    47  type DatabaseSummaryProps = DatabaseSummaryExplicitData & DatabaseSummaryConnectedData & DatabaseSummaryActions;
    48  
    49  // DatabaseSummaryBase implements common lifecycle methods for DatabaseSummary
    50  // components, which differ primarily by their render() method.
    51  // TODO(mrtracy): We need to find a better abstraction for the common
    52  // "refresh-on-mount-or-receiveProps" we have in many of our connected
    53  // components; that would allow us to avoid this inheritance.
    54  export class DatabaseSummaryBase extends React.Component<DatabaseSummaryProps, {}> {
    55    // loadTableDetails loads data for each table which have no info in the store.
    56    // TODO(mrtracy): Should this be refreshing data always? Not sure if there
    57    // is a performance concern with invalidation periods.
    58    loadTableDetails(props = this.props) {
    59      if (props.tableInfos && props.tableInfos.length > 0) {
    60        _.each(props.tableInfos, (tblInfo) => {
    61          if (_.isUndefined(tblInfo.numColumns)) {
    62            props.refreshTableDetails(new protos.cockroach.server.serverpb.TableDetailsRequest({
    63              database: props.name,
    64              table: tblInfo.name,
    65            }));
    66          }
    67          if (_.isUndefined(tblInfo.physicalSize)) {
    68            props.refreshTableStats(new protos.cockroach.server.serverpb.TableStatsRequest({
    69              database: props.name,
    70              table: tblInfo.name,
    71            }));
    72          }
    73        });
    74      }
    75    }
    76  
    77    // Refresh when the component is mounted.
    78    componentDidMount() {
    79      this.props.refreshDatabaseDetails(new protos.cockroach.server.serverpb.DatabaseDetailsRequest({ database: this.props.name }));
    80      this.loadTableDetails();
    81    }
    82  
    83    // Refresh when the component receives properties.
    84    componentDidUpdate() {
    85      this.loadTableDetails(this.props);
    86    }
    87  
    88    render(): React.ReactElement<any> {
    89        throw new Error("DatabaseSummaryBase should never be instantiated directly. ");
    90    }
    91  }
    92  
    93  export function databaseDetails(state: AdminUIState) {
    94    return state.cachedData.databaseDetails;
    95  }
    96  
    97  // Function which returns TableInfo objects for all tables in a database. This
    98  // is not a selector, because it is not based only on the Redux state - it is
    99  // also based on the tables in a single database.
   100  // TODO(mrtracy): look into using a component like reselect-map if this proves
   101  // to be expensive. My current intuition is that this will not be a bottleneck.
   102  export function tableInfos(state: AdminUIState, dbName: string) {
   103    const dbDetails = databaseDetails(state);
   104    const tableNames = dbDetails[dbName] && dbDetails[dbName].data && dbDetails[dbName].data.table_names;
   105    if (!tableNames) {
   106      return null;
   107    }
   108    const details = state.cachedData.tableDetails;
   109    const stats =  state.cachedData.tableStats;
   110    return _.map(tableNames, (tableName) => {
   111      const tblId = generateTableID(dbName, tableName);
   112      const tblDetails = details[tblId] && details[tblId].data;
   113      const tblStats = stats[tblId] && stats[tblId].data;
   114      return new TableInfo(tableName, tblDetails, tblStats);
   115    });
   116  }
   117  
   118  // Function which extracts the grants for a single database from redux state.
   119  export function grants(state: AdminUIState, dbName: string) {
   120      const dbDetails = databaseDetails(state);
   121      return dbDetails[dbName] && dbDetails[dbName].data && dbDetails[dbName].data.grants;
   122  }