Skip to content

Commit

Permalink
Add an example for data change querying with Rails
Browse files Browse the repository at this point in the history
  • Loading branch information
exAspArk committed Mar 8, 2024
1 parent 2712d2d commit 64127d0
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 28 deletions.
28 changes: 13 additions & 15 deletions docs/docs/orms/prisma.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ npx prisma migrate dev

## Usage

Enable the new [Prisma driver adapters](https://www.prisma.io/docs/orm/overview/databases/database-drivers) to use a native [PostgreSQL client](https://github.com/brianc/node-postgres) for Node.js by adding the following in your `schema.prisma`:
Enable the new [Prisma driver adapters](https://www.prisma.io/docs/orm/overview/databases/database-drivers) to use a native [PostgreSQL client](https://github.com/brianc/node-postgres) for Node.js by adding the following:

```
```prisma title="prisma/schema.prisma"
generator client {
previewFeatures = ["driverAdapters"]
...
Expand All @@ -46,7 +46,7 @@ generator client {

Enable PostgreSQL adapter for your Prisma client by using `withPgAdapter`:

```js
```ts title="src/prisma.ts"
import { withPgAdapter } from "@bemi-db/prisma";
import { PrismaClient } from '@prisma/client';

Expand All @@ -63,7 +63,7 @@ Now you can specify custom application context that will be automatically passed

Add the `setContext` [Express.js](https://expressjs.com/) middleware to pass application context with all underlying data changes within made an HTTP request:

```ts
```ts title="src/index.ts"
import { setContext } from "@bemi-db/prisma";
import express, { Request } from "express";

Expand All @@ -83,7 +83,7 @@ app.use(

If you use [Apollo Server](https://www.apollographql.com/docs/apollo-server), it's possible use the `BemiApolloServerPlugin` to pass application context with all underlying data changes made within a GraphQL request:

```ts
```ts title="src/apollo-server.ts"
import { BemiApolloServerPlugin } from "@bemi-db/prisma";
import { ApolloServer } from "@apollo/server";

Expand All @@ -104,7 +104,7 @@ new ApolloServer({

With [Next.js](https://github.com/vercel/next.js) API Routes, it is possible to use the `bemiContext` function to set application context in a handler function:

```ts
```ts title="pages/api/endpoint.ts"
import { bemiContext } from "@bemi-db/prisma";
import type { NextApiRequest, NextApiResponse } from "next";

Expand All @@ -118,7 +118,7 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) {

Alternatively, you can use our Express.js-compatible `setContext` middleware with [next-connect](https://github.com/hoangvvo/next-connect):

```ts
```ts title="pages/api/endpoint.ts"
import { setContext } from "@bemi-db/prisma";
import { createRouter, expressWrapper } from "next-connect";
import type { NextApiRequest, NextApiResponse } from "next";
Expand All @@ -143,7 +143,7 @@ Note that Next.js middlewares are not supported because they cannot be executed

It is also possible to manually set or override context by using the `bemiContext` function:

```ts
```ts title="src/my-worker.ts"
import { bemiContext } from "@bemi-db/prisma";

const MyWorker = () => {
Expand All @@ -155,7 +155,7 @@ const MyWorker = () => {
}
```

See [this repo](https://github.com/BemiHQ/bemi-prisma-example) as an Todo app example with Prisma that automatically tracks all changes.
See this [example repo](https://github.com/BemiHQ/bemi-prisma-example) as an Todo app example with Prisma that automatically tracks all changes.

### SSL

Expand All @@ -176,9 +176,7 @@ Connect your PostgreSQL source database on [bemi.io](https://bemi.io) to start i
Once your destination PostgreSQL database has been fully provisioned, you'll see a "Connected" status. You can now test the connection after making database changes in your connected source database:

```
psql -h us-west-1-prod-destination-pool.ctbxbtz4ojdc.us-west-1.rds.amazonaws.com -p 5432 -U u_9adb30103a55 -d db_9adb30103a55 -c \
'SELECT "primary_key", "table", "operation", "before", "after", "context", "committed_at" FROM changes;'
Password for user u_9adb30103a55:
psql -h [HOSTNAME] -U [USERNAME] -d [DATABASE] -c 'SELECT "primary_key", "table", "operation", "before", "after", "context", "committed_at" FROM changes;'
primary_key | table | operation | before | after | context | committed_at
-------------+-------+-----------+---------------------------------------------------+----------------------------------------------------+---------------------------------------------------------------------------------------------+------------------------
Expand All @@ -195,9 +193,9 @@ See [Destination Database](/postgresql/destination-database) for more details.

Lastly, connect to the Bemi PostgreSQL destination database to easily query change data from your application.

To query the read-only historical data, add a new Prisma schema in `prisma/bemi.prisma`
To query the read-only historical data, add a new Prisma schema

```prisma
```prisma title="prisma/bemi.prisma"
datasource db {
provider = "postgresql"
url = "postgresql://[USERNAME]:[PASSWORD]@[DESTINATION_HOST]:5432/[DESTINATION_DATABASE]"
Expand Down Expand Up @@ -233,7 +231,7 @@ npx prisma generate --schema prisma/bemi.prisma

Initialize a new Prisma client connected to the destination database:

```tsx
```tsx title="src/bemiPrisma.ts"
import { PrismaClient } from '../prisma/generated/bemi'

const bemiPrisma = new PrismaClient()
Expand Down
63 changes: 57 additions & 6 deletions docs/docs/orms/rails.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ This Ruby gem is a recommended Ruby on Rails integration, enabling you to pass a

## Installation

1. Install the gem by adding it to your `Gemfile`
1. Install the gem

```
```rb title="Gemfile"
gem 'bemi-rails'
```

Expand All @@ -37,7 +37,7 @@ bin/rails db:migrate

Now you can easily specify custom application context that will be automatically passed with all data changes.

```rb
```rb title="app/controllers/application_controller.rb"
class ApplicationController < ActionController::Base
before_action :set_bemi_context

Expand All @@ -59,6 +59,7 @@ Application context:
* Is used only with `INSERT`, `UPDATE`, `DELETE` SQL queries performed via Active Record. Otherwise, it is a no-op.
* Is passed directly into PG [Write-Ahead Log](https://www.postgresql.org/docs/current/wal-intro.html) with data changes without affecting the structure of the database and SQL queries.

See this [example repo](https://github.com/BemiHQ/bemi-rails-example) as a Ruby on Rails Todo app that automatically tracks all changes.

## Data change tracking

Expand All @@ -69,9 +70,7 @@ Connect your PostgreSQL source database on [bemi.io](https://bemi.io) to start i
Once your destination PostgreSQL database has been fully provisioned, you'll see a "Connected" status. You can now test the connection after making database changes in your connected source database:

```
psql -h us-west-1-prod-destination-pool.ctbxbtz4ojdc.us-west-1.rds.amazonaws.com -p 5432 -U u_9adb30103a55 -d db_9adb30103a55 -c \
'SELECT "primary_key", "table", "operation", "before", "after", "context", "committed_at" FROM changes;'
Password for user u_9adb30103a55:
psql -h [HOSTNAME] -U [USERNAME] -d [DATABASE] -c 'SELECT "primary_key", "table", "operation", "before", "after", "context", "committed_at" FROM changes;'
primary_key | table | operation | before | after | context | committed_at
-------------+--------+-----------+-------------------------------------------------+--------------------------------------------------+------------------------------------------------------------------------------------------+------------------------
Expand All @@ -84,6 +83,58 @@ Password for user u_9adb30103a55:

See [Destination Database](/postgresql/destination-database) for more details.

## Data change querying

Lastly, connect to the Bemi PostgreSQL destination database to easily query change data from your application.

To query historical data, configure an additional [database connection with Active Record](https://guides.rubyonrails.org/active_record_multiple_databases.html):

```yml title="config/database.yml"
production:
primary:
<<: *default
# Your regular database settings go here
bemi:
adapter: postgresql
encoding: unicode
pool: <%= ENV["RAILS_MAX_THREADS"] || 5 %>
host: <%= ENV["DESTINATION_DB_HOST"] %>
port: <%= ENV["DESTINATION_DB_PORT"] %>
database: <%= ENV["DESTINATION_DB_DATABASE"] %>
username: <%= ENV["DESTINATION_DB_USERNAME"] %>
password: <%= ENV["DESTINATION_DB_PASSWORD"] %>
migrations_paths: db/bemi_migrate
```
Create a new model that connects to the destination database:
```rb title="app/models/bemi_record.rb"
# frozen_string_literal: true

class BemiRecord < ApplicationRecord
self.abstract_class = true
connects_to database: { writing: :bemi, reading: :bemi }
end
```

Create a new `Change` model to access all data changes:

```rb title="app/models/change.rb"
# frozen_string_literal: true

class Change < BemiRecord
end
```

Query changes from the destination database:

```rb
changes = Change.where(table: 'todos')
.where('"context" @> ?', { user_id: 1}.to_json)
.order(committed_at: :desc)
.limit(1)
```

## Alternative gems

| | [Bemi](https://github.com/BemiHQ/bemi-rails)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | [PaperTrail](https://github.com/paper-trail-gem/paper_trail) | [Audited](https://github.com/collectiveidea/audited)&nbsp;&nbsp;&nbsp;&nbsp; | [Logidze](https://github.com/palkan/logidze)&nbsp;&nbsp;&nbsp;&nbsp; |
Expand Down
12 changes: 5 additions & 7 deletions docs/docs/orms/typeorm.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

This package is a recommended TypeORM integration, enabling you to pass application-specific context when performing database changes. This can include context such as the 'where' (API endpoint, worker, etc.), 'who' (user, cron job, etc.), and 'how' behind a change, thereby enriching the information captured by Bemi.

See [this repo](https://github.com/BemiHQ/bemi-typeorm-example) as an Todo app example with TypeORM that automatically tracks all changes.
See this [example repo](https://github.com/BemiHQ/bemi-typeorm-example) as an Todo app example with TypeORM that automatically tracks all changes.

## Prerequisites

Expand Down Expand Up @@ -39,7 +39,7 @@ npx typeorm migration:run

Add an [Express](https://expressjs.com/) middleware to pass application context with all underlying data changes within an HTTP request:

```ts
```ts title="src/index.ts"
import { setContext } from "@bemi-db/typeorm";
import express, { Request } from "express";
import { AppDataSource } from "./data-source";
Expand Down Expand Up @@ -74,9 +74,7 @@ The database connection details can be securely configured through the [dashboar
Once your destination PostgreSQL database has been fully provisioned, you'll see a "Connected" status. You can now test the connection after making database changes in your connected source database:

```
psql -h us-west-1-prod-destination-pool.ctbxbtz4ojdc.us-west-1.rds.amazonaws.com -p 5432 -U u_9adb30103a55 -d db_9adb30103a55 -c \
'SELECT "primary_key", "table", "operation", "before", "after", "context", "committed_at" FROM changes;'
Password for user u_9adb30103a55:
psql -h [HOSTNAME] -U [USERNAME] -d [DATABASE] -c 'SELECT "primary_key", "table", "operation", "before", "after", "context", "committed_at" FROM changes;'
primary_key | table | operation | before | after | context | committed_at
-------------+-------+-----------+---------------------------------------------------+----------------------------------------------------+---------------------------------------------------------------------------------------------+------------------------
Expand All @@ -95,7 +93,7 @@ Lastly, connect directly to the Bemi PostgreSQL database to easily query change

To query the read-only historical data, add the Bemi destination database to TypeORM using [multiple data source](https://typeorm.io/multiple-data-sources#using-multiple-data-sources). Configuration setting are found directly on the [Bemi dashboard](https://dashboard.bemi.io/log-in/):

```ts
```ts title="src/data-source.ts"
import { DataSource } from "typeorm";
import { Change } from "@bemi-db/typeorm";

Expand Down Expand Up @@ -128,7 +126,7 @@ export const BemiDataSource = new DataSource({

Initialize the BemiDataSource the same place you would your main AppDataSource

```ts
```ts title="src/index.ts"
BemiDataSource.initialize()
.then(() => {
console.log("Connected to Bemi");
Expand Down
1 change: 1 addition & 0 deletions docs/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ const config: Config = {
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
additionalLanguages: ['ruby'],
},
} satisfies Preset.ThemeConfig,
};
Expand Down

0 comments on commit 64127d0

Please sign in to comment.