-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Generate insert and select methods for context object under db (#…
…177) Co-authored-by: Darun Seethammagari <[email protected]>
- Loading branch information
Showing
13 changed files
with
544 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ | |
redis/ | ||
*.log | ||
/indexer/blocks/ | ||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import pgFormat from 'pg-format'; | ||
import DmlHandler from './dml-handler'; | ||
|
||
describe('DML Handler tests', () => { | ||
const hasuraClient: any = { | ||
getDbConnectionParameters: jest.fn().mockReturnValue({ | ||
database: 'test_near', | ||
host: 'postgres', | ||
password: 'test_pass', | ||
port: 5432, | ||
username: 'test_near' | ||
}) | ||
}; | ||
let PgClient: any; | ||
let query: any; | ||
|
||
const ACCOUNT = 'test_near'; | ||
const SCHEMA = 'test_schema'; | ||
const TABLE_NAME = 'test_table'; | ||
|
||
beforeEach(() => { | ||
query = jest.fn().mockReturnValue({ rows: [] }); | ||
PgClient = jest.fn().mockImplementation(() => { | ||
return { query, format: pgFormat }; | ||
}); | ||
}); | ||
|
||
test('Test valid insert one with array', async () => { | ||
const inputObj = { | ||
account_id: 'test_acc_near', | ||
block_height: 999, | ||
block_timestamp: 'UTC', | ||
content: 'test_content', | ||
receipt_id: 111, | ||
accounts_liked: JSON.stringify(['cwpuzzles.near', 'devbose.near']) | ||
}; | ||
|
||
const dmlHandler = new DmlHandler(ACCOUNT, hasuraClient, PgClient); | ||
|
||
await dmlHandler.insert(SCHEMA, TABLE_NAME, [inputObj]); | ||
expect(query.mock.calls).toEqual([ | ||
['INSERT INTO test_schema.test_table (account_id,block_height,block_timestamp,content,receipt_id,accounts_liked) VALUES (\'test_acc_near\', \'999\', \'UTC\', \'test_content\', \'111\', \'["cwpuzzles.near","devbose.near"]\') RETURNING *;', []] | ||
]); | ||
}); | ||
|
||
test('Test valid insert multiple rows with array', async () => { | ||
const inputObj = [{ | ||
account_id: 'morgs_near', | ||
block_height: 1, | ||
receipt_id: 'abc', | ||
}, | ||
{ | ||
account_id: 'morgs_near', | ||
block_height: 2, | ||
receipt_id: 'abc', | ||
}]; | ||
|
||
const dmlHandler = new DmlHandler(ACCOUNT, hasuraClient, PgClient); | ||
|
||
await dmlHandler.insert(SCHEMA, TABLE_NAME, [inputObj]); | ||
expect(query.mock.calls).toEqual([ | ||
['INSERT INTO test_schema.test_table (0,1) VALUES (\'{"account_id":"morgs_near","block_height":1,"receipt_id":"abc"}\'::jsonb, \'{"account_id":"morgs_near","block_height":2,"receipt_id":"abc"}\'::jsonb) RETURNING *;', []] | ||
]); | ||
}); | ||
|
||
test('Test valid select on two fields', async () => { | ||
const inputObj = { | ||
account_id: 'test_acc_near', | ||
block_height: 999, | ||
}; | ||
|
||
const dmlHandler = new DmlHandler(ACCOUNT, hasuraClient, PgClient); | ||
|
||
await dmlHandler.select(SCHEMA, TABLE_NAME, inputObj); | ||
expect(query.mock.calls).toEqual([ | ||
['SELECT * FROM test_schema.test_table WHERE account_id=$1 AND block_height=$2', Object.values(inputObj)] | ||
]); | ||
}); | ||
|
||
test('Test valid select on two fields with limit', async () => { | ||
const inputObj = { | ||
account_id: 'test_acc_near', | ||
block_height: 999, | ||
}; | ||
|
||
const dmlHandler = new DmlHandler(ACCOUNT, hasuraClient, PgClient); | ||
|
||
await dmlHandler.select(SCHEMA, TABLE_NAME, inputObj, 1); | ||
expect(query.mock.calls).toEqual([ | ||
['SELECT * FROM test_schema.test_table WHERE account_id=$1 AND block_height=$2 LIMIT 1', Object.values(inputObj)] | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { wrapError } from '../utility'; | ||
import PgClientModule from '../pg-client'; | ||
import HasuraClient from '../hasura-client/hasura-client'; | ||
|
||
export default class DmlHandler { | ||
private pgClient!: PgClientModule; | ||
private readonly initialized: Promise<void>; | ||
|
||
constructor ( | ||
private readonly account: string, | ||
private readonly hasuraClient: HasuraClient = new HasuraClient(), | ||
private readonly PgClient = PgClientModule, | ||
) { | ||
this.initialized = this.initialize(); | ||
} | ||
|
||
private async initialize (): Promise<void> { | ||
const connectionParameters = await this.hasuraClient.getDbConnectionParameters(this.account); | ||
this.pgClient = new this.PgClient({ | ||
user: connectionParameters.username, | ||
password: connectionParameters.password, | ||
host: process.env.PGHOST, | ||
port: Number(connectionParameters.port), | ||
database: connectionParameters.database, | ||
}); | ||
} | ||
|
||
async insert (schemaName: string, tableName: string, objects: any[]): Promise<any[]> { | ||
await this.initialized; // Ensure constructor completed before proceeding | ||
if (!objects?.length) { | ||
return []; | ||
} | ||
|
||
const keys = Object.keys(objects[0]); | ||
// Get array of values from each object, and return array of arrays as result. Expects all objects to have the same number of items in same order | ||
const values = objects.map(obj => keys.map(key => obj[key])); | ||
const query = `INSERT INTO ${schemaName}.${tableName} (${keys.join(',')}) VALUES %L RETURNING *;`; | ||
|
||
const result = await wrapError(async () => await this.pgClient.query(this.pgClient.format(query, values), []), `Failed to execute '${query}' on ${schemaName}.${tableName}.`); | ||
if (result.rows?.length === 0) { | ||
console.log('No rows were inserted.'); | ||
} | ||
return result.rows; | ||
} | ||
|
||
async select (schemaName: string, tableName: string, object: any, limit: number | null = null): Promise<any[]> { | ||
await this.initialized; // Ensure constructor completed before proceeding | ||
|
||
const keys = Object.keys(object); | ||
const values = Object.values(object); | ||
const param = Array.from({ length: keys.length }, (_, index) => `${keys[index]}=$${index + 1}`).join(' AND '); | ||
let query = `SELECT * FROM ${schemaName}.${tableName} WHERE ${param}`; | ||
if (limit !== null) { | ||
query = query.concat(' LIMIT ', Math.round(limit).toString()); | ||
} | ||
|
||
const result = await wrapError(async () => await this.pgClient.query(this.pgClient.format(query), values), `Failed to execute '${query}' on ${schemaName}.${tableName}.`); | ||
if (!(result.rows && result.rows.length > 0)) { | ||
console.log('No rows were selected.'); | ||
} | ||
return result.rows; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './dml-handler'; |
Oops, something went wrong.