Skip to content

Commit 37d157e

Browse files
Merge pull request #312 from Canner/develop
Bump to 0.10.0
2 parents 7e87aa7 + d9cea9e commit 37d157e

File tree

99 files changed

+3006
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+3006
-118
lines changed

README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,32 @@
1919
<img alt="" src="https://img.shields.io/badge/-@vulcansql-orange?style=for-the-badge&logo=twitter&logoColor=white&labelColor=gray&logoWidth=20">
2020
</a>
2121
<a href="https://img.shields.io/codecov/c/gh/Canner/vulcan-sql" >
22-
<img alt="" src="https://img.shields.io/codecov/c/gh/Canner/vulcan-sql?style=for-the-badge&labelColor=gray&logoColor=white&logoWidth=20"/>
22+
<img alt="" src="https://img.shields.io/codecov/c/gh/Canner/vulcan-sql?style=for-the-badge&color=orange&labelColor=gray&logoColor=white&logoWidth=20"/>
2323
</a>
2424
</p>
2525

26-
## What is VulcanSQL
26+
## What is VulcanSQL?
2727

28-
**[VulcanSQL](https://vulcansql.com/) is a Data API Framework for data applications** that helps data folks create and share data APIs faster. It turns your SQL templates into data APIs. No backend skills required.
28+
**[VulcanSQL](https://vulcansql.com/) is an Analytical Data API Framework for data apps**. It aims to help data professionals deliver RESTful APIs from databases, data warehouses or data lakes much easier and faster. It turns your SQL queries into REST APIs in no time!
2929

3030
![overview of VulcanSQL](https://i.imgur.com/JvCIZQ1.png)
3131

32-
## Online Playground
32+
## What Problems does VulcanSQL aim to solve?
3333

34-
Use [Online Playground](https://codesandbox.io/p/sandbox/vulcansql-demo-wfd834) to get a taste of VulcanSQL!
34+
Given the vast amount of analytical data in databases, data warehouses, and data lakes, there is currently no easy method for data professionals to share data with relevant stakeholders for operational business use cases.
3535

36-
## Examples
36+
## Online Playground
3737

38-
Need Inspiration?! Discover a [selected compilation of examples](https://github.com/Canner/vulcan-sql-examples) showcasing the use of VulcanSQL!
38+
Use [Online Playground](https://codesandbox.io/p/sandbox/vulcansql-demo-wfd834) to get a taste of VulcanSQL!
3939

4040
## Installation
4141

4242
Please visit [the installation guide](https://vulcansql.com/docs/get-started/installation).
4343

44+
## Examples
45+
46+
Need inspiration? Here are a [selected compilation of examples](https://github.com/Canner/vulcan-sql-examples) showcasing how you can use VulcanSQL!
47+
4448
## How VulcanSQL works?
4549

4650
💻 **Build**
@@ -49,7 +53,7 @@ VulcanSQL offers a development experience similar to dbt. Just insert variables
4953

5054
🚀 **Accelerate**
5155

52-
VulcanSQL uses DuckDB as a caching layer, boosting your query speed and API response time . This means faster, smoother data APIs for you and less strain on your data sources.
56+
VulcanSQL uses DuckDB as a caching layer, boosting your query speed and reducing API response time. This means faster, smoother data APIs for you and less strain on your data sources.
5357

5458
🔥 **Deploy**
5559

@@ -82,7 +86,7 @@ Below are some common scenarios that you may be interested:
8286

8387
👏 **Data sharing**: Sharing data with partners, vendors, or customers, which requires a secure and scalable way to expose data.
8488

85-
⚙️ **Internal tools**: Integration with internal tools like AppSmith and Retools, etc.
89+
⚙️ **Internal tools**: Integration with internal tools like Zapier, AppSmith and Retools, etc.
8690

8791
## Community
8892

codecov.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,13 @@ flag_management:
33
# Reference of past coverage for tests that are not run on current commit.
44
# https://docs.codecov.com/docs/carryforward-flags
55
carryforward: true
6+
coverage:
7+
status:
8+
patch: false
9+
project:
10+
default:
11+
target: auto
12+
threshold: "80%"
13+
base: auto
14+
flags:
15+
- unit

packages/build/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@vulcan-sql/build",
33
"description": "VulcanSQL package for building projects",
4-
"version": "0.9.1",
4+
"version": "0.10.0",
55
"type": "commonjs",
66
"publishConfig": {
77
"access": "public"
@@ -22,6 +22,6 @@
2222
},
2323
"license": "Apache-2.0",
2424
"peerDependencies": {
25-
"@vulcan-sql/core": "~0.9.1-0"
25+
"@vulcan-sql/core": "~0.10.0-0"
2626
}
2727
}

packages/catalog-server/lib/api.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import axios from 'axios';
22
import { errorCode } from '@vulcan-sql/catalog-server/utils/errorCode';
3+
import getConfig from 'next/config';
4+
5+
const { publicRuntimeConfig } = getConfig();
36

47
enum API {
58
Login = '/api/auth/login',
@@ -22,7 +25,7 @@ const handleError = ({ statusCode, errorMessage }) => {
2225
};
2326

2427
export const axiosInstance = axios.create({
25-
baseURL: process.env.API_URL || 'http://localhost:4200',
28+
baseURL: publicRuntimeConfig.baseUrl,
2629
responseType: 'json',
2730
timeout: 30000,
2831
headers: {

packages/catalog-server/lib/apollo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
import { setContext } from '@apollo/client/link/context';
88

99
const httpLink = createHttpLink({
10-
uri: process.env.GQL_API_URL || 'http://localhost:4200/api/graphql',
10+
uri: '/api/graphql',
1111
});
1212

1313
const authLink = setContext((_, { headers }) => {

packages/catalog-server/next.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ const nextConfig = {
1212
compiler: {
1313
styledComponents: true,
1414
},
15+
publicRuntimeConfig: {
16+
baseUrl: process.env.BASE_URL || 'http://localhost:4200',
17+
},
1518
serverRuntimeConfig: {
1619
// Will only be available on the server side
1720
vulcanSQLHost: process.env.VULCAN_SQL_HOST || 'http://localhost:3000',

packages/catalog-server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@vulcan-sql/catalog-server",
33
"description": "Catalog server for VulcanSQL",
4-
"version": "0.9.1",
4+
"version": "0.10.0",
55
"publishConfig": {
66
"access": "public"
77
},

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@vulcan-sql/cli",
33
"description": "CLI tools for VulcanSQL",
4-
"version": "0.9.1",
4+
"version": "0.10.0",
55
"type": "commonjs",
66
"bin": {
77
"vulcan": "./src/index.js"

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@vulcan-sql/core",
33
"description": "Core package of VulcanSQL",
4-
"version": "0.9.1",
4+
"version": "0.10.0",
55
"type": "commonjs",
66
"publishConfig": {
77
"access": "public"

packages/core/src/containers/modules/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ExtensionLoader } from '../../lib/extension-loader';
33
import { ICoreOptions } from '../../models/coreOptions';
44
import templateEngineModules from '../../lib/template-engine/built-in-extensions';
55
import validatorModule from '../../lib/validators/built-in-validators';
6+
import LoggerModule from '../../lib/loggers';
67
import {
78
builtInCodeLoader,
89
builtInTemplateProvider,
@@ -23,6 +24,7 @@ export const extensionModule = (options: ICoreOptions) =>
2324
for (const templateEngineModule of templateEngineModules) {
2425
loader.loadInternalExtensionModule(templateEngineModule);
2526
}
27+
loader.loadInternalExtensionModule(LoggerModule);
2628
// Validator (single module)
2729
loader.loadInternalExtensionModule(validatorModule);
2830
// Template provider (single module)

packages/core/src/containers/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,6 @@ export const TYPES = {
5252
Extension_CompilerLoader: Symbol.for('Extension_CompilerLoader'),
5353
Extension_DataSource: Symbol.for('Extension_DataSource'),
5454
Extension_ProfileReader: Symbol.for('ProfileReader'),
55+
// Logger
56+
Extension_ActivityLogger: Symbol.for('Extension_ActivityLogger'),
5557
};

packages/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './lib/utils';
22
export * from './lib/validators';
3+
export * from './lib/loggers';
34
export * from './lib/template-engine';
45
export * from './lib/artifact-builder';
56
export * from './lib/data-query';

packages/core/src/lib/cache-layer/cacheLayerLoader.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export class CacheLayerLoader implements ICacheLayerLoader {
2222
private options: ICacheLayerOptions;
2323
private cacheStorage: DataSource;
2424
private logger = getLogger({ scopeName: 'CORE' });
25-
2625
constructor(
2726
@inject(TYPES.CacheLayerOptions) options: CacheLayerOptions,
2827
@inject(TYPES.Factory_DataSource)
@@ -43,7 +42,14 @@ export class CacheLayerLoader implements ICacheLayerLoader {
4342
templateName: string,
4443
cache: CacheLayerInfo
4544
): Promise<void> {
46-
const { cacheTableName, sql, profile, indexes, folderSubpath } = cache;
45+
const {
46+
cacheTableName,
47+
sql,
48+
profile,
49+
indexes,
50+
folderSubpath,
51+
options: cacheOptions,
52+
} = cache;
4753
const type = this.options.type!;
4854
const dataSource = this.dataSourceFactory(profile);
4955

@@ -82,6 +88,7 @@ export class CacheLayerLoader implements ICacheLayerLoader {
8288
directory,
8389
profileName: profile,
8490
type,
91+
options: cacheOptions,
8592
});
8693
} else {
8794
this.logger.debug(

packages/core/src/lib/cache-layer/cacheLayerRefresher.ts

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
import ms, { StringValue } from 'ms';
22
import { uniq } from 'lodash';
33
import { ToadScheduler, SimpleIntervalJob, AsyncTask } from 'toad-scheduler';
4-
import { inject, injectable } from 'inversify';
4+
import { inject, injectable, multiInject } from 'inversify';
55
import { TYPES } from '@vulcan-sql/core/types';
6-
import { APISchema } from '@vulcan-sql/core/models';
6+
import {
7+
APISchema,
8+
ActivityLogContentOptions,
9+
ActivityLogType,
10+
CacheLayerInfo,
11+
IActivityLogger,
12+
} from '@vulcan-sql/core/models';
713
import { ConfigurationError } from '../utils/errors';
814
import { ICacheLayerLoader } from './cacheLayerLoader';
15+
import { getLogger } from '../utils';
16+
import moment = require('moment');
917

18+
enum RefreshResult {
19+
SUCCESS = 'SUCCESS',
20+
FAILED = 'FAILED',
21+
}
1022
export interface ICacheLayerRefresher {
1123
/**
1224
* Start the job to load the data source to cache storage and created tables from cache settings in schemas
@@ -22,9 +34,16 @@ export interface ICacheLayerRefresher {
2234
export class CacheLayerRefresher implements ICacheLayerRefresher {
2335
private cacheLoader: ICacheLayerLoader;
2436
private scheduler = new ToadScheduler();
37+
private activityLoggers: IActivityLogger[];
38+
private logger = getLogger({ scopeName: 'CORE' });
2539

26-
constructor(@inject(TYPES.CacheLayerLoader) loader: ICacheLayerLoader) {
40+
constructor(
41+
@inject(TYPES.CacheLayerLoader) loader: ICacheLayerLoader,
42+
@multiInject(TYPES.Extension_ActivityLogger)
43+
activityLoggers: IActivityLogger[]
44+
) {
2745
this.cacheLoader = loader;
46+
this.activityLoggers = activityLoggers;
2847
}
2948

3049
public async start(
@@ -53,16 +72,14 @@ export class CacheLayerRefresher implements ICacheLayerRefresher {
5372
const refreshJob = new SimpleIntervalJob(
5473
{ milliseconds, runImmediately },
5574
new AsyncTask(workerId, async () => {
56-
// load data the to cache storage
57-
58-
await this.cacheLoader.load(templateName, cache);
75+
await this.loadCacheAndSendActivityLog(schema, cache);
5976
}),
6077
{ preventOverrun: true, id: workerId }
6178
);
6279
// add the job to schedule cache refresh task
6380
this.scheduler.addIntervalJob(refreshJob);
6481
} else {
65-
await this.cacheLoader.load(templateName, cache);
82+
await this.loadCacheAndSendActivityLog(schema, cache);
6683
}
6784
})
6885
);
@@ -77,6 +94,44 @@ export class CacheLayerRefresher implements ICacheLayerRefresher {
7794
this.scheduler.stop();
7895
}
7996

97+
private async loadCacheAndSendActivityLog(
98+
schema: APISchema,
99+
cache: CacheLayerInfo
100+
) {
101+
const { urlPath } = schema;
102+
const { sql } = cache;
103+
let refreshResult = RefreshResult.SUCCESS;
104+
const now = moment.utc().format('YYYY-MM-DD HH:mm:ss');
105+
const templateName = schema.templateSource.replace('/', '_');
106+
try {
107+
// get the current time in format of UTC
108+
await this.cacheLoader.load(templateName, cache);
109+
} catch (error: any) {
110+
refreshResult = RefreshResult.FAILED;
111+
this.logger.debug(`Failed to refresh cache: ${error}`);
112+
} finally {
113+
// send activity log
114+
const content = {
115+
isSuccess: refreshResult === RefreshResult.SUCCESS ? true : false,
116+
activityLogType: ActivityLogType.CACHE_REFRESH,
117+
logTime: now,
118+
urlPath,
119+
sql,
120+
} as ActivityLogContentOptions;
121+
const activityLoggers = this.getActivityLoggers();
122+
for (const activityLogger of activityLoggers)
123+
activityLogger.log(content).catch((err: any) => {
124+
this.logger.debug(
125+
`Failed to log activity after refreshing cache: ${err}`
126+
);
127+
});
128+
}
129+
}
130+
131+
private getActivityLoggers(): IActivityLogger[] {
132+
return this.activityLoggers.filter((logger) => logger.isEnabled());
133+
}
134+
80135
private checkDuplicateCacheTableName(schemas: APISchema[]) {
81136
const tableNames = schemas
82137
// => [[table1, table2], [table1, table3], [table4]]

0 commit comments

Comments
 (0)