@datawheel/olap-client v2.1.6
@datawheel/olap-client
Javascript client to interact with mondrian-rest and tesseract-olap servers.
This package is the sucessor of the mondrian-rest-client and the @datawheel/tesseract-client packages.
Installation
npm install @datawheel/olap-clientClient initialization
import {Client, MondrianDataSource, TesseractDataSource} from "@datawheel/olap-client"
// Create an instance of the DataSource according to the type of server
const datasource = new MondrianDataSource("https://your.mondrian-rest.server/");
// ...and pass it as the parameter to initialize your client
const client = new Client(datasource);The constructor parameter is optional. You can also set/reset the datasource afterwards:
const client = new Client();
// ...
const datasource = new TesseractDataSource("https://another.tesseract-olap.server/olap/");
client.setDataSource(datasource);If you don't know beforehand, use the Client.fromURL(url) static method. It will do some requests to try and guess the type of datasource.
// Using Promise chaining
let unknownClient;
Client.fromURL("https://unknown.server/olap/").then(client => {
unknownClient = client;
});
// Using async/await
const unknownClient = await Client.fromURL("https://unknown.server/olap/");If you really need the client object directly, you can initialize the instance and add the DataSource later:
const client = new Client();
// ...
Client.dataSourceFromURL("https://unknown.server/olap/").then(datasource => {
client.setDataSource(datasource);
});Notice if you try to interact with a method of an IClient instance without a configured DataSource, it will throw an error.
MultiClient initialization
import {MultiClient, TesseractDataSource} from "@datawheel/olap-client"
// MultiClient instances can also be initialized with or without a datasource
const client = new MultiClient();
// To add a datasource, use the #addDataSource() method instead of #setDataSource()
const datasource = new TesseractDataSource("https://your.mondrian-rest.server/");
client.addDataSource(datasource);You can pass multiple datasources to the MultiClient#addDataSource() method:
client.addDataSource(datasourceA, datasourceB, datasourceC);And likewise Client, if you don't know beforehand, you can let the client guess the type of datasource:
const unknownClient = MultiClient.fromURL("https://unknown.server/olap/", "https://another.server/", ...);Usage
Both Client and MultiClient instances follow the IClient interface. Client and MultiClient-specific methods are at the end.
interface IClient
IClient#getCubes
getCubes(): Promise<Cube[]>Returns a promise that resolves to a Cube array.
In a MultiClient instance, the cubes from all the subscribed datasources are concatenated.
IClient#getCube
getCube(cubeName: string, selectorFn?: (cubes: Cube[]) => Cube): Promise<Cube>Returns a promise that resolves to a single Cube instance, whose .name is equal to the cubeName parameter.
In a MultiClient instance, if there's more than one cube with the same cubeName, a selectorFn function can be used to pick the right cube.
IClient#getMembers
getMembers(levelRef: Level | LevelDescriptor, options?: any): Promise<Member[]>Returns a promise that resolves to a list of the members available for the level referenced.levelRef can be a Level instance, or an object describing how to find a Level in a DataSource. For more information on this object, see the specification of the LevelDescriptor interface.
the properties options
IClient#getMember
getMember(levelRef: Level | LevelDescriptor, key: string | number, options?: any): Promise<Member>Returns a promise that resolves to a member for the level referenced, specified by its key.
IClient#execQuery
execQuery(query: Query, endpoint?: string): Promise<Aggregation>Execute a query in all the available datasources. The returned object implements the Aggregation interface.
The query parameter must be a Query instance, usually obtained from a Cube instance.
class Client
Client#checkStatus
checkStatus(): Promise<ServerStatus>Returns an object with information about the server. For now, only supports detailed info about Tesseract OLAP, but tries its best with Mondrian REST anyway.
Client#setDataSource
setDataSource(datasource: IDataSource): voidSets the datasource the client instance will work with.
The datasource parameter must be an object compatible with the IDataSource interface.
Client.dataSourceFromURL
static dataSourceFromURL(url: string): Promise<IDataSource>Tries to guess the type of server from a request to the serverUrl. The parameter must be a string.
Since a request must be done beforehand, this static method returns a Promise that resolves to a object compatible with the IDataSource interface.
Client.fromURL
static fromURL(url: string): Promise<Client>Using the result from Client.dataSourceFromURL(serverUrl), generates a new Client(datasource) instance.
class MultiClient
MultiClient#addDataSource
addDataSource(...datasources: IDataSource[]): voidAdds datasources to the client internal directory.
The datasources must be objects compatible with the IDataSource interface.
MultiClient#checkStatus
checkStatus(): Promise<ServerStatus[]>Returns an array of objects with information about each datasource server. These objects have the same structure of response as Client#checkStatus.
MultiClient.dataSourcesFromURL
static dataSourcesFromURL(...serverUrls: string[]): Promise<IDataSource[]>Does a request to each url in serverUrls, tries to guess the type of server, and returns the respective datasource.
This method returns a Promise that resolves to an array of IDataSource.
MultiClient.fromURL
static fromURL(...serverUrls: string[]): Promise<MultiClient>From the result from MultiClient.dataSourcesFromURL(...serverUrls), generates a single new MultiClient(...datasources) instance.
This method returns a Promise that resolves to a MultiClient instance.
Other interfaces
interface Aggregation
interface Aggregation<T = any> {
data: T;
query: Query;
status?: number;
url?: string;
}The result of executing a Query is represented by an object implementing the Aggregation interface.
The type of the data property depends on the format set on the Query:
Format.jsonrecordsreturns an array of tidy data objects- All other
Formats return the raw data returned by the server
interface LevelDescriptor
interface LevelDescriptor {
server?: string; // Server URL
cube?: string; // Cube name
dimension?: string; // Dimension name
hierarchy?: string; // Hierarchy name
level: string; // Level name, required
}A LevelDescriptor is an ordinary object with enough info to differentiate a Level in a list of DataSources. Depending on the circumstances (e.g. some name is shared in more than one object) some Levels might need more information on a LevelDescriptor to be differentiated. All the properties are the names of the parents, except for server that maps to the URL of the DataSource. Level is the only required at all times.
It is suggested to fill the properties with as much information as possible to prevent getting a different level.
interface ServerStatus
interface ServerStatus {
software: string;
online: boolean;
url: string;
version: string;
}Contains information about the current state of the server.
Due to server implementation, version isn't available from MondrianDataSource.
interface IDataSource
This package integrates the TesseractDataSource and MondrianDataSource classes, but the clients can work with any object that implements the IDataSource interface correctly:
interface IDataSource {
serverOnline: boolean;
serverSoftware: string;
serverVersion: string;
serverUrl: string;
checkStatus(): Promise<ServerStatus>;
execQuery(query: Query, endpoint?: string): Promise<Aggregation>;
fetchCube(cubeName: string): Promise<AdaptedCube>;
fetchCubes(): Promise<AdaptedCube[]>;
fetchMember(parent: Level, key: string | number, options?: any): Promise<AdaptedMember>;
fetchMembers(parent: Level, options?: any): Promise<AdaptedMember[]>;
}Check the source code to see the requirements of the AdaptedObjects interfaces and how the current data sources are implemented.
Example
Client.fromURL("https://chilecube.datachile.io")
.then(client => {
return client.getCube("tax_data").then(cube => {
const query = cube.query;
query
.addMeasure("Labour")
.addDrilldown("Year")
.setOption("debug", false)
.setOption("distinct", false)
.setOption("nonempty", true);
return client.execQuery(query);
});
})
.then(aggregation => {
console.log(aggregation);
});License
MIT © 2019 Datawheel
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago