From ee4cbb8891e0899eb92b64e8cf3a3ae63edd1bab Mon Sep 17 00:00:00 2001 From: Ali Demirci Date: Fri, 12 Nov 2021 15:41:48 +0300 Subject: [PATCH 1/2] Update README.md --- README.md | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0d18a4b..3fb3069 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,132 @@ $ npm i --save @depyronick/nestjs-clickhouse ## Quick Start -- to be documented +### Importing the module +Once the installation process is complete, we can import the `ClickHouseModule` into the root `AppModule`. + +```typescript +import { Module } from '@nestjs/common'; +import { ClickHouseModule } from '@depyronick/nestjs-clickhouse'; + +@Module({ + imports: [ + ClickHouseModule.register([{ + name: 'ANALYTICS_SERVER', + host: '127.0.0.1', + password: '7h3ul71m473p4555w0rd' + }]) + ], +}) +export class AppModule {} +``` +The `register()` method will register a ClickHouse client with the specified connection options. See **[ClickHouseOptions](https://github.com/depyronick/nestjs-clickhouse/blob/main/lib/interfaces/ClickHouseModuleOptions.ts "ClickHouseOptions")** object for more information. Each registered client should have an unique `name` definition. The default value for `name` property is `CLICKHOUSE_DEFAULT`. This property will be used as an injection token. + +### Interacting with ClickHouse Client + +To interact with the ClickHouse server that you have just registered, inject it to your class using the injection token. + +```typescript +constructor( + @Inject('ANALYTICS_SERVER') + private analyticsServer: ClickHouseClient +) {} +``` +> The `ClickHouseClient` class is imported from the `@depyronick/nestjs-clickhouse`. + +There are two methods to interact with the server: + +### `ClickHouseClient.query(query: string): Observable` + +```typescript +import { Inject, Injectable } from '@nestjs/common'; +import { ClickHouseClient } from '@depyronick/nestjs-clickhouse'; + +interface ExampleRowData { + timestamp: number; + ip: string; + userAgent: string; + os: string; + version: string; + // ... +} + +@Injectable() +export class AppService { + constructor( + @Inject('ANALYTICS_SERVER') + private readonly analyticsServer: ClickHouseClient + ) { + this + .analyticsServer + .query("SELECT * FROM visits LIMIT 10") + .subscribe({ + error: (err: any): void => { + // called when an error occurred during query + }, + next: (row): void => { + // called for each row + // the type of row property here is ExampleRowData + }, + complete: (): void => { + // called when stream is completed + } + }) + } +} +``` + +### `ClickHouseClient.insert(table: string, data: T[]): Observable` + +```typescript +import { Inject, Injectable } from '@nestjs/common'; +import { ClickHouseClient } from '@depyronick/nestjs-clickhouse'; + +interface ExampleRowData { + timestamp: number; + ip: string; + userAgent: string; + os: string; + version: string; + // ... +} + +@Injectable() +export class AppService { + constructor( + @Inject('ANALYTICS_SERVER') + private readonly analyticsServer: ClickHouseClient + ) { + this + .analyticsServer + .insert("visits", [{ + timestamp: new Date().getTime(), + ip: '127.0.0.1', + os: 'OSX', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', + version: "1.0.0" + }]) + .subscribe({ + error: (err: any): void => { + // called when an error occurred during insert + }, + next: (): void => { + // currently next does not emits anything for inserts + }, + complete: (): void => { + // called when insert is completed + } + }) + } +} +``` + +## Notes +- This repository will be actively maintained and improved. +- Currently only supports JSON format. + - Planning to support all applicable formats listed [here](https://clickhouse.com/docs/en/interfaces/formats/ "here"). +- Planning to implement TCP protocol, if ClickHouse decides to [documentate](https://clickhouse.com/docs/en/interfaces/tcp/ "documentate") it. +- Planning to implement inserts with streams. +- This library supports http response compressions such as brotli, gzip and deflate. ## Support @@ -44,4 +169,4 @@ Nest is an MIT-licensed open source project. It can grow thanks to the sponsors ## License -[MIT licensed](LICENSE). \ No newline at end of file +[MIT licensed](LICENSE). From 5b9950042d2d8d2ad0dd43b4ad0d4199c2680186 Mon Sep 17 00:00:00 2001 From: Ali Demirci Date: Fri, 12 Nov 2021 16:08:05 +0300 Subject: [PATCH 2/2] Update README.md --- README.md | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3fb3069..c55f265 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ There are two methods to interact with the server: import { Inject, Injectable } from '@nestjs/common'; import { ClickHouseClient } from '@depyronick/nestjs-clickhouse'; -interface ExampleRowData { +interface VisitsTable { timestamp: number; ip: string; userAgent: string; @@ -89,14 +89,14 @@ export class AppService { ) { this .analyticsServer - .query("SELECT * FROM visits LIMIT 10") + .query("SELECT * FROM visits LIMIT 10") .subscribe({ error: (err: any): void => { // called when an error occurred during query }, next: (row): void => { // called for each row - // the type of row property here is ExampleRowData + // the type of row property here is VisitsTable }, complete: (): void => { // called when stream is completed @@ -108,11 +108,16 @@ export class AppService { ### `ClickHouseClient.insert(table: string, data: T[]): Observable` +The `insert` method accepts two inputs. +- `table` is the name of the table that you'll be inserting data to. + - Table value could be prefixed with database like `analytics_db.visits`. +- `data: T[]` array of JSON objects to insert. + ```typescript import { Inject, Injectable } from '@nestjs/common'; import { ClickHouseClient } from '@depyronick/nestjs-clickhouse'; -interface ExampleRowData { +interface VisitsTable { timestamp: number; ip: string; userAgent: string; @@ -129,11 +134,11 @@ export class AppService { ) { this .analyticsServer - .insert("visits", [{ + .insert("visits", [{ timestamp: new Date().getTime(), ip: '127.0.0.1', os: 'OSX', - userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36', + userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/95.0.4638.69 Safari/537.36', version: "1.0.0" }]) .subscribe({ @@ -151,6 +156,39 @@ export class AppService { } ``` +## Multiple Clients +You can register multiple clients in the same application as follows: + +```typescript +@Module({ + imports: [ + ClickHouseModule.register([{ + name: 'ANALYTICS_SERVER', + host: '127.0.0.1', + password: '7h3ul71m473p4555w0rd' + }, { + name: 'CHAT_SERVER', + host: '192.168.1.110', + password: 'ch5ts3rv3Rp455w0rd' + }]) + ], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule { } +``` +Then you can interact with these servers using their assigned injection tokens. + +```typescript +constructor( + @Inject('ANALYTICS_SERVER') + private analyticsServer: ClickHouseClient, + + @Inject('CHAT_SERVER') + private chatServer: ClickHouseClient +) { } +``` + ## Notes - This repository will be actively maintained and improved. - Currently only supports JSON format.