File

src/app/core/services/data-source/data-source.service.ts

Description

Backend data queries.

Index

Properties
Methods

Constructor

constructor(globalConfig: GlobalConfigState<CCFDatabaseOptions>)

Creates an instance of data source service.

Parameters :
Name Type Optional
globalConfig GlobalConfigState<CCFDatabaseOptions> No

Methods

getAggregateResults
getAggregateResults(filter?: Filter)

Queries for aggregate values.

Parameters :
Name Type Optional Description
filter Filter Yes

Currently applied filter.

Returns : Observable<AggregateResult[]>

An observable emitting the results.

getCellTypeTermOccurences
getCellTypeTermOccurences(filter?: Filter)

Queries for cell type term counts.

Parameters :
Name Type Optional Description
filter Filter Yes

Currently applied filter.

Returns : Observable<Record<string, number>>

An observable emitting the results.

getCellTypeTreeModel
getCellTypeTreeModel()

Get the cell type tree model.

Returns : Observable<OntologyTreeModel>

An observable emitting the results.

getOntologyTermOccurences
getOntologyTermOccurences(filter?: Filter)

Queries for ontology term counts.

Parameters :
Name Type Optional Description
filter Filter Yes

Currently applied filter.

Returns : Observable<Record<string, number>>

An observable emitting the results.

getOntologyTreeModel
getOntologyTreeModel()

Get the ontology tree model.

Returns : Observable<OntologyTreeModel>

An observable emitting the results.

getOrganScene
getOrganScene(organ: string, filter?: Filter)
Parameters :
Name Type Optional
organ string No
filter Filter Yes
Returns : Observable<SpatialSceneNode[]>
getReferenceOrgans
getReferenceOrgans()

Get the reference organs.

Returns : Observable<SpatialEntity[]>

An observable emitting the results.

getScene
getScene(filter?: Filter)

Queries for scene nodes to display.

Parameters :
Name Type Optional Description
filter Filter Yes

Currently applied filter.

Returns : Observable<SpatialSceneNode[]>

An observable emitting the results.

getTissueBlockResults
getTissueBlockResults(filter?: Filter)

Queries for tissue block values.

Parameters :
Name Type Optional Description
filter Filter Yes

Currently applied filter.

Returns : Observable<TissueBlockResult[]>

An observable emitting the results.

Properties

dataSource
Type : Observable<DataSource>

The underlying database.

dbOptions
Type : CCFDatabaseOptions

Database initialization options.

import { Injectable, OnDestroy } from '@angular/core';
import {
  AggregateResult,
  CCFDatabase,
  CCFDatabaseOptions,
  DEFAULT_CCF_DB_OPTIONS,
  Filter,
  OntologyTreeModel,
  SpatialEntity,
  SpatialSceneNode,
  TissueBlockResult,
} from 'ccf-database';
import { GlobalConfigState } from 'ccf-shared';
import { Remote } from 'comlink';
import { Observable, Subscription, Unsubscribable, using } from 'rxjs';
import { distinctUntilChanged, map, filter as rxFilter, shareReplay, switchMap, take } from 'rxjs/operators';

import { environment } from '../../../../environments/environment';

type DataSource = Remote<CCFDatabase> | CCFDatabase;

function compareConfig(previous: CCFDatabaseOptions, current: CCFDatabaseOptions): boolean {
  return previous === current;
}

/**
 * Backend data queries.
 */
@Injectable({
  providedIn: 'root',
})
export class DataSourceService implements OnDestroy {
  /** The underlying database. */
  dataSource: Observable<DataSource>;
  /** Database initialization options. */
  dbOptions!: CCFDatabaseOptions;

  private readonly subscriptions = new Subscription();

  /**
   * Creates an instance of data source service.
   */
  constructor(globalConfig: GlobalConfigState<CCFDatabaseOptions>) {
    this.dataSource = globalConfig.getOption('data').pipe(
      map((data) => ({ ...DEFAULT_CCF_DB_OPTIONS, dataSources: data })),
      rxFilter((config) => Object.keys(config).length > 0),
      map((config) => config as unknown as CCFDatabaseOptions),
      distinctUntilChanged(compareConfig),
      switchMap((config) =>
        using(
          () => this.createDataSource(),
          (resource) => this.connectDataSource((resource as unknown as { source: DataSource }).source, config),
        ),
      ),
      shareReplay(1),
    );

    this.subscriptions.add(this.dataSource.subscribe());
  }

  ngOnDestroy(): void {
    this.subscriptions.unsubscribe();
  }

  /**
   * Queries for tissue block values.
   *
   * @param [filter] Currently applied filter.
   * @returns An observable emitting the results.
   */
  getTissueBlockResults(filter?: Filter): Observable<TissueBlockResult[]> {
    return this.dataSource.pipe(
      switchMap((db) => db.getTissueBlockResults(filter)),
      take(1),
    );
  }

  /**
   * Queries for aggregate values.
   *
   * @param [filter] Currently applied filter.
   * @returns An observable emitting the results.
   */
  getAggregateResults(filter?: Filter): Observable<AggregateResult[]> {
    return this.dataSource.pipe(
      switchMap((db) => db.getAggregateResults(filter)),
      take(1),
    );
  }

  /**
   * Queries for ontology term counts.
   *
   * @param [filter] Currently applied filter.
   * @returns An observable emitting the results.
   */
  getOntologyTermOccurences(filter?: Filter): Observable<Record<string, number>> {
    return this.dataSource.pipe(
      switchMap((db) => db.getOntologyTermOccurences(filter)),
      take(1),
    );
  }

  /**
   * Queries for cell type term counts.
   *
   * @param [filter] Currently applied filter.
   * @returns An observable emitting the results.
   */
  getCellTypeTermOccurences(filter?: Filter): Observable<Record<string, number>> {
    return this.dataSource.pipe(
      switchMap((db) => db.getCellTypeTermOccurences(filter)),
      take(1),
    );
  }

  /**
   * Get the ontology tree model.
   *
   * @returns An observable emitting the results.
   */
  getOntologyTreeModel(): Observable<OntologyTreeModel> {
    return this.dataSource.pipe(
      switchMap((db) => db.getOntologyTreeModel()),
      take(1),
    );
  }

  /**
   * Get the cell type tree model.
   *
   * @returns An observable emitting the results.
   */
  getCellTypeTreeModel(): Observable<OntologyTreeModel> {
    return this.dataSource.pipe(
      switchMap((db) => db.getCellTypeTreeModel()),
      take(1),
    );
  }

  /**
   * Get the reference organs.
   *
   * @returns An observable emitting the results.
   */
  getReferenceOrgans(): Observable<SpatialEntity[]> {
    return this.dataSource.pipe(
      switchMap((db) => db.getReferenceOrgans()),
      take(1),
    );
  }

  /**
   * Queries for scene nodes to display.
   *
   * @param [filter] Currently applied filter.
   * @returns An observable emitting the results.
   */
  getScene(filter?: Filter): Observable<SpatialSceneNode[]> {
    return this.dataSource.pipe(
      switchMap((db) => db.getScene(filter)),
      take(1),
    );
  }

  getOrganScene(organ: string, filter?: Filter): Observable<SpatialSceneNode[]> {
    return this.dataSource.pipe(
      switchMap((db) => db.getReferenceOrganScene(organ, filter)),
      take(1),
    );
  }

  private createDataSource(): { source: DataSource } & Unsubscribable {
    const unsubscribe: () => void = () => undefined;
    const source = new CCFDatabase();

    return { source, unsubscribe };
  }

  private async connectDataSource(source: DataSource, config: CCFDatabaseOptions): Promise<DataSource> {
    const start = new Date().getTime();

    await source.connect(config, false);

    if (!environment.production) {
      // eslint-disable-next-line no-console
      console.info(`Loaded CCF database in ${(new Date().getTime() - start) / 1000}s`);
      // eslint-disable-next-line no-console
      console.log(source);
    }
    return source;
  }
}

results matching ""

    No results matching ""