Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions labs/playground1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
result.json
spec-oas3.yaml
.vulcan-debug
68 changes: 68 additions & 0 deletions labs/playground1/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

.PHONY: install build start pkg-core pkg-build pkg-serve pkg-cli clean

# start vulcan server (default goal)
start: install build test-data/moma.db ../../node_modules
@vulcan start

# install node modules and like playground extensions
install:
@yarn; \
cd ./playground-exts; \
yarn link; \
cd ..; \
yarn link "playground-exts"

# build the required packages
build: pkg-core pkg-build pkg-serve pkg-cli

# build for core pakge
pkg-core: ../../node_modules
@cd ../..; \
yarn nx build core; \
mkdir -p ./labs/playground1/node_modules/@vulcan-sql; \
rm -rf ./labs/playground1/node_modules/@vulcan-sql/core; \
cp -R ./dist/packages/core ./labs/playground1/node_modules/@vulcan-sql

# build for build pakge
pkg-build: ../../node_modules
@cd ../..; \
yarn nx build build; \
mkdir -p ./labs/playground1/node_modules/@vulcan-sql; \
rm -rf ./labs/playground1/node_modules/@vulcan-sql/build; \
cp -R ./dist/packages/build ./labs/playground1/node_modules/@vulcan-sql

# build for serve pakge
pkg-serve: ../../node_modules
@cd ../..; \
yarn nx build serve; \
mkdir -p ./labs/playground1/node_modules/@vulcan-sql; \
rm -rf ./labs/playground1/node_modules/@vulcan-sql/serve; \
cp -R ./dist/packages/serve ./labs/playground1/node_modules/@vulcan-sql

# build and install for cli pakge
pkg-cli: ../../node_modules
@cd ../..; \
yarn nx install cli;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why we copy the vulcan dist core, build and serve to labs/playgrounds/node_modules/@vulcan-sql, but not include cli ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLI package will be installed as a global package via npm, that is, it will be copied to .npm folder instead.


test-data/artists.csv:
@echo "downloading artists.csv ..."; \
curl -s -o "test-data/artists.csv" "https://media.githubusercontent.com/media/MuseumofModernArt/collection/master/Artists.csv"

test-data/artworks.csv:
@echo "downloading artworks.csv ..."; \
curl -s -o "test-data/artworks.csv" "https://media.githubusercontent.com/media/MuseumofModernArt/collection/master/Artworks.csv"

test-data/moma.db: test-data/artists.csv test-data/artworks.csv
@cd test-data; \
node getdata.js

# install node modules for parent folder
../../node_modules: ../../package.json
@cd ../..; \
yarn

clean:
@rm -rf node_modules; \
rm -rf test-data/*.csv; \
rm -rf test-data/moma.db
21 changes: 21 additions & 0 deletions labs/playground1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Playground 1 - Basic Vulcan project with MoMA dataset

This project contains these resources for testing your development:

- Latest Vulcan packages that are built from local files.
- Basic Vulcan configuration.
- In-memory data warehouse - [DuckDB](https://duckdb.org/) and its driver.
- Testing data: [The Museum of Modern Art (MoMA)](https://github.com/MuseumofModernArt/collection).

## Install

```bash
cd ./lab/playground1
make
```

- This command installs Vulcan CLI too, you can use `vulcan start` instead of `make` if the source codes aren’t changed.

## Testing Data

After installation, you can find `artists.csv` and `artworks.csv` under folder `test-data`. They are the data we used for this playground. You can also access the data base via [DuckDB CLI](https://duckdb.org/docs/api/cli): `duckdb ./test-data/moma.db`
8 changes: 8 additions & 0 deletions labs/playground1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "my-first-vulcan-project",
"dependencies": {
"duckdb": "^0.4.0",
"lodash": "^4.17.21",
"redoc": "^2.0.0-rc.76"
}
}
3 changes: 3 additions & 0 deletions labs/playground1/playground-exts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const { MockDataSource } = require('./mockDb');

exports.MockDataSource = MockDataSource;
93 changes: 93 additions & 0 deletions labs/playground1/playground-exts/mockDb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
const { DataSource, EXTENSION_IDENTIFIER_METADATA_KEY } = require('@vulcan-sql/core');
const { Stream } = require('stream');
const duckdb = require('duckdb');
const path = require('path');
const db = new duckdb.Database(path.resolve(__dirname, '..', 'test-data', 'moma.db'));
const _ = require('lodash');
// TODO: create logger from core package;
const { Logger } = require('tslog');
const logger = new Logger({
name: 'duckdb',
minLevel: 'info',
exposeErrorCodeFrame: false,
displayFilePath: 'hidden',
displayFunctionName: false,
});

const getType = (value) => {
const jsType = typeof (value);
switch (jsType) {
case 'boolean': return 'boolean';
case 'number': return 'number';
default: return 'string';
}
}

class MockDataSource extends DataSource {
async execute(options) {
const { statement, bindParams } = options;
// handle parameterized query statement
let query = statement;

const parameters =
// {$1: 'v1', $3: 'v3', $2: 'v2' }
_.chain(bindParams)
// [[$1, 'v1'], [$3, 'v3'], [$2, 'v2']]
.toPairs()
// [[$1, 'v1'], [$2, 'v2'], [$3, 'v3']]
.orderBy(([name,]) => Number(name.slice(1)))
// ['v1,'v2','v3']
.map(([_, value]) => value)
.value()


return new Promise((resolve, reject) => {
logger.info(query, parameters);
db.all(query, ...parameters, function (err, res) {
if (err) {
return reject(err)
}
const readStream = new Stream.Readable({
objectMode: true,
read: () => null,
});
res.forEach((r) => readStream.push(r));
readStream.push(null);

return resolve({
getColumns: () => {
if (!res[0]) return [];
return Object.keys(res[0]).map(name => ({
name, type: getType(res[0][name])
}))
},
getData: () => {
return readStream;
},
})

});
})

}

async prepare(params) {
const identifiers = {};
const binds = {};
let index = 1;
for (const key of Object.keys(params)) {
const identifier = `$${index}`;
identifiers[key] = identifier;
binds[identifier] = params[key];
index += 1;
}
return {
identifiers,
binds,
};
}
}

Reflect.defineMetadata(EXTENSION_IDENTIFIER_METADATA_KEY, 'duck', MockDataSource);

exports.MockDataSource = MockDataSource
4 changes: 4 additions & 0 deletions labs/playground1/playground-exts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "playground-exts",
"main": "index.js"
}
5 changes: 5 additions & 0 deletions labs/playground1/sqls/artist/artist.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
select
*
from "artists"
where
ConstituentID = {{ context.params.id }}
7 changes: 7 additions & 0 deletions labs/playground1/sqls/artist/artist.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
urlPath: /artist/:id
request:
- fieldName: id
fieldIn: path
description: constituent id
validators:
- required
5 changes: 5 additions & 0 deletions labs/playground1/sqls/artist/works.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
select
*
from "artworks"
where
concat(', ' , ConstituentID , ',') like concat('%, ', {{ context.params.id }} , ',%');
7 changes: 7 additions & 0 deletions labs/playground1/sqls/artist/works.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
urlPath: /artist/:id/works
request:
- fieldName: id
fieldIn: path
description: constituent id
validators:
- required
3 changes: 3 additions & 0 deletions labs/playground1/test-data/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.csv
moma.db.wal
moma.db
29 changes: 29 additions & 0 deletions labs/playground1/test-data/getdata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env node

const fs = require('fs');
const duckdb = require('duckdb');

console.log('remove db file');
if (fs.existsSync('moma.db'))
fs.unlinkSync('moma.db');

const db = new duckdb.Database('moma.db');

async function runQuery(query) {
return new Promise((resolve, reject) => {
db.run(query, (err, res) => {
if (err) return reject(err);
return resolve(res);
});
})
}

(async () => {
console.log('inserting artists.csv ...');
await runQuery(`create table artists as select * from "artists.csv"`);
console.log('done.');

console.log('inserting artworks.csv ...');
await runQuery(`create table artworks as select * from "artworks.csv"`);
console.log('done.');
})();
34 changes: 34 additions & 0 deletions labs/playground1/vulcan.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: playground1
description: A starter Vulcan project
version: 0.1.0-alpha.1
template:
provider: LocalFile
# Path to .sql files
folderPath: sqls
codeLoader: InMemory
artifact:
provider: LocalFile
serializer: JSON
# Path to build result
filePath: result.json
schema-parser:
reader: LocalFile
# Path to .yaml files
folderPath: sqls
document-generator:
specs:
- oas3
folderPath: .
types:
- RESTFUL
extensions:
mockDb: playground-exts
executor:
type: "duck"
rate-limit:
options:
interval:
min: 1
max: 10000
enforce-https:
enabled: false
Loading