Skip to content

Commit 482eb37

Browse files
committed
chore: setup docs
1 parent 1e9e213 commit 482eb37

25 files changed

+18123
-99
lines changed

Diff for: .cspell.json

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"Carnaval",
1414
"chrono",
1515
"Cidade",
16+
"clsx",
1617
"Creedence",
1718
"dagrejs",
1819
"DATEPART",
@@ -56,6 +57,7 @@
5657
"Sucesso",
5758
"testcontainers",
5859
"tsdoc",
60+
"typeof",
5961
"verybigthings"
6062
],
6163
"flagWords": [],

Diff for: .github/workflows/deploy-docs.yml

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Deploy docs to GitHub Pages
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
# Review gh actions docs if you want to further define triggers, paths, etc
8+
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
9+
10+
defaults:
11+
run:
12+
working-directory: ./docs
13+
14+
jobs:
15+
build:
16+
name: Build Docusaurus
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
- uses: actions/setup-node@v4
23+
with:
24+
node-version: 18
25+
cache: npm
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
- name: Build website
30+
31+
run: npm run build
32+
33+
- name: Upload Build Artifact
34+
uses: actions/upload-pages-artifact@v3
35+
with:
36+
path: docs/build
37+
38+
deploy:
39+
name: Deploy to GitHub Pages
40+
needs: build
41+
42+
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
43+
permissions:
44+
pages: write # to deploy to Pages
45+
id-token: write # to verify the deployment originates from an appropriate source
46+
47+
# Deploy to the github-pages environment
48+
environment:
49+
name: github-pages
50+
url: ${{ steps.deployment.outputs.page_url }}
51+
52+
runs-on: ubuntu-latest
53+
steps:
54+
- name: Deploy to GitHub Pages
55+
id: deployment
56+
uses: actions/deploy-pages@v4

Diff for: .github/workflows/test-deploy-docs.yml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Test docs deployment
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
# Review gh actions docs if you want to further define triggers, paths, etc
8+
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
9+
10+
defaults:
11+
run:
12+
working-directory: ./docs
13+
14+
jobs:
15+
test-deploy:
16+
name: Test deployment
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
- uses: actions/setup-node@v4
23+
with:
24+
node-version: 18
25+
cache: npm
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
- name: Test build website
30+
run: npm run build

Diff for: README.md

+46-98
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,33 @@
44
![NPM](https://img.shields.io/npm/v/@verybigthings/semantic-layer)
55
![GitHub Workflow Status](https://github.com/verybigthings/semantic-layer/actions/workflows/semantic-layer.yml/badge.svg?branch=main)
66

7-
## Introduction
7+
# Quick Start Guide
88

9-
The `@verybigthings/semantic-layer` library is crafted to simplify interactions between applications and relational databases, by providing a framework that abstracts SQL query complexities into a more manageable form. It aids in constructing analytical queries while addressing common issues such as join fanout and chasm traps. The library intelligently determines optimal join strategies for requested models, based on their definitions within the database. Designed for direct integration into existing code bases, it operates without the need for deploying external services.
9+
Welcome to the semantic layer library! Let's dive in and create a simple data model in just a few steps.
1010

11-
## Key Features
11+
## Installation
1212

13-
- **Declarative Schema and Query Building:** Utilize a fluent, TypeScript-based API to define your database schema and queries declaratively.
14-
- **Type Safety:** Minimize errors with type-safe interfaces for query construction, enhancing code reliability.
15-
- **Dynamic SQL Query Generation:** Automatically construct complex SQL queries tailored to your application's business logic, eliminating the need for string concatenation.
13+
First, let's get the library installed (use npm or a package manager of your choice):
1614

17-
## Getting Started
18-
19-
### Installation
20-
21-
To integrate the Semantic Layer Library into your project, run the following command with npm:
22-
23-
```shell
15+
```bash
2416
npm install @verybigthings/semantic-layer
2517
```
2618

27-
## Usage Examples
19+
## Building Your First Semantic Layer
2820

29-
### Defining Models and Fields
21+
Imagine you're running a music store. You have customers, and they make purchases. Let's model this!
3022

31-
This library allows you to define models and their respective fields, including dimensions and metrics, which represent the various columns and computed values within your database.
23+
### Step 1: Create Your Models
3224

33-
**Defining a Model:**
25+
We'll create two models: `customers` and `invoices`.
3426

3527
```typescript
3628
import * as semanticLayer from "@verybigthings/semantic-layer";
3729

30+
// Our Customers model
3831
const customersModel = semanticLayer
3932
.model()
40-
.withName("customers")
33+
.withName("customers")
4134
.fromTable("Customer")
4235
.withDimension("customer_id", {
4336
type: "number",
@@ -53,128 +46,83 @@ const customersModel = semanticLayer
5346
sql: ({ model }) => model.column("LastName"),
5447
});
5548

49+
// Our Invoices model
5650
const invoicesModel = semanticLayer
5751
.model()
58-
.withName("invoices")
52+
.withName("invoices")
5953
.fromTable("Invoice")
6054
.withDimension("invoice_id", {
6155
type: "number",
6256
primaryKey: true,
63-
sql: ({ model, sql }) => sql`${model.column("InvoiceId")}`,
64-
})
65-
.withMetric("total", {
66-
// node-postgres returns string types for big integers
67-
type: "string",
68-
aggregateWith: "sum",
69-
sql: ({ model }) => model.column("Total"),
70-
});
71-
72-
const invoiceLinesModel = semanticLayer
73-
.model()
74-
.withName("invoice_lines")
75-
.fromTable("InvoiceLine")
76-
.withDimension("invoice_line_id", {
77-
type: "number",
78-
primaryKey: true,
79-
sql: ({ model }) => model.column("InvoiceLineId"),
80-
})
81-
.withDimension("invoice_id", {
82-
type: "number",
8357
sql: ({ model }) => model.column("InvoiceId"),
8458
})
85-
.withDimension("track_id", {
59+
.withDimension("customer_id", {
8660
type: "number",
87-
sql: ({ model }) => model.column("TrackId"),
61+
sql: ({ model }) => model.column("CustomerId"),
8862
})
89-
.withMetric("quantity", {
90-
// node-postgres returns string types for big integers
91-
type: "string",
92-
aggregateWith: "sum",
93-
sql: ({ model }) => model.column("Quantity"),
94-
})
95-
.withMetric("total_unit_price", {
96-
// node-postgres returns string types for big integers
97-
98-
type: "string",
99-
aggregateWith: "sum"
100-
sql: ({ model }) => model.column("UnitPrice"),
63+
.withMetric("total", {
64+
type: "number",
65+
description: "Invoice total.",
66+
sql: ({ model, sql }) => sql`SUM(COALESCE(${model.column("Total")}, 0))`,
10167
});
10268
```
10369

104-
**Defining a Repository and joining models:**
70+
### Step 2: Create a Repository
71+
72+
Now, let's put these models together in a repository:
10573

10674
```typescript
10775
const repository = semanticLayer
10876
.repository()
10977
.withModel(customersModel)
11078
.withModel(invoicesModel)
111-
.withModel(invoiceLinesModel)
11279
.joinOneToMany(
11380
"customers",
11481
"invoices",
115-
({ sql, dimensions }) =>
116-
sql`${dimensions.customers.customer_id} = ${dimensions.invoices.customer_id}`
117-
)
118-
.joinOneToMany(
119-
"invoices",
120-
"invoice_lines",
121-
({ sql, dimensions }) =>
122-
sql`${dimensions.invoices.invoice_id} = ${dimensions.invoice_lines.invoice_id}`
82+
({ sql, models }) =>
83+
sql`${models.customers.dimension(
84+
"customer_id"
85+
)} = ${models.invoices.dimension("customer_id")}`
12386
);
124-
125-
const queryBuilder = repository.build("postgresql");
12687
```
12788

128-
### Data Querying
89+
### Step 3: Build a Query
12990

130-
Leverage the library's querying capabilities to fetch dimensions and metrics, apply filters, and sort results efficiently.
91+
With our repository set up, we can now build queries:
13192

13293
```typescript
133-
// Dimension and metric query
94+
const queryBuilder = repository.build("postgresql");
95+
13496
const query = queryBuilder.buildQuery({
135-
dimensions: ["customers.customer_id"],
136-
metrics: ["invoices.total"],
97+
members: [
98+
"customers.customer_id",
99+
"customers.first_name",
100+
"customers.last_name",
101+
"invoices.total",
102+
],
137103
order: { "customers.customer_id": "asc" },
138104
limit: 10,
139105
});
106+
```
140107

141-
// Metric query with filters
142-
const query = queryBuilder.buildQuery({
143-
metrics: ["invoices.total", "invoice_lines.quantity"],
144-
filters: [
145-
{ operator: "equals", member: "customers.customer_id", value: [1] },
146-
],
147-
});
108+
### Step 4: Execute the Query
148109

149-
// Dimension query with filters
150-
const query = queryBuilder.buildQuery({
151-
dimensions: ["customers.first_name", "customers.last_name"],
152-
filters: [
153-
{ operator: "equals", member: "customers.customer_id", value: [1] },
154-
],
155-
});
110+
The `query` object contains the SQL string and bindings. You can use these with your preferred database client:
156111

157-
// Filtering and sorting
158-
const query = queryBuilder.buildQuery({
159-
dimensions: ["customers.first_name"],
160-
metrics: ["invoices.total"],
161-
filters: [{ operator: "gt", member: "invoices.total", value: [100] }],
162-
order: { "invoices.total": "desc" },
163-
});
112+
```typescript
113+
const result = await someSqlClient.query(query.sql, query.bindings);
164114
```
165115

166-
### Executing queries
167-
168-
Note: `@verybigthings/semantic-layer` focuses on SQL generation. Execute the generated queries with your SQL client:
116+
For example, with the `pg` package for PostgreSQL:
169117

170118
```typescript
171-
const result = await sqlClient.query(query.sql, query.bindings);
119+
const result = await pg.query(query.sql, query.bindings);
172120
```
173121

174-
### Limitations
122+
And there you have it! You've just set up a semantic layer for your music store data. This layer will make it easy to analyze customer purchases without writing complex SQL queries each time.
175123

176-
At the moment, only PostgreSQL queries are generated correctly. We're working on adding support for additional dialects.
124+
Read the [documentation](https://verybigthings.github.io/semantic-layer/) for more information.
177125

178126
## Acknowledgments
179127

180-
`@verybigthings/semantic-layer` draws inspiration from several BI libraries, particularly [Cube.dev](https://cube.dev). While our API is very close to that of Cube.dev, future development may change our approach.
128+
`@verybigthings/semantic-layer` draws inspiration from several BI libraries, particularly [Cube.dev](https://cube.dev). While our API was initially inspired by Cube.dev, it has since diverged based on our own needs and preferences.

Diff for: biome.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"node_modules",
77
"coverage",
88
"vitest.config.ts",
9-
"scripts/build.ts"
9+
"scripts/build.ts",
10+
"docs"
1011
]
1112
},
1213
"formatter": {

Diff for: docs/.gitignore

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Dependencies
2+
/node_modules
3+
4+
# Production
5+
/build
6+
7+
# Generated files
8+
.docusaurus
9+
.cache-loader
10+
11+
# Misc
12+
.DS_Store
13+
.env.local
14+
.env.development.local
15+
.env.test.local
16+
.env.production.local
17+
18+
npm-debug.log*
19+
yarn-debug.log*
20+
yarn-error.log*

Diff for: docs/README.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Website
2+
3+
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
4+
5+
### Installation
6+
7+
```
8+
$ yarn
9+
```
10+
11+
### Local Development
12+
13+
```
14+
$ yarn start
15+
```
16+
17+
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
18+
19+
### Build
20+
21+
```
22+
$ yarn build
23+
```
24+
25+
This command generates static content into the `build` directory and can be served using any static contents hosting service.
26+
27+
### Deployment
28+
29+
Using SSH:
30+
31+
```
32+
$ USE_SSH=true yarn deploy
33+
```
34+
35+
Not using SSH:
36+
37+
```
38+
$ GIT_USER=<Your GitHub username> yarn deploy
39+
```
40+
41+
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

Diff for: docs/babel.config.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3+
};

0 commit comments

Comments
 (0)