Skip to content

Commit

Permalink
Merge pull request bcc-code#17 from bcc-code/feat/postgres-has-auto-i…
Browse files Browse the repository at this point in the history
…ncrement

add functions for forcing auto increment (serial data type) on postgres
  • Loading branch information
u12206050 authored Jan 25, 2024
2 parents 1057202 + 468a225 commit 5500975
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 1 deletion.
121 changes: 121 additions & 0 deletions src/dialects/postgres/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import assert from "node:assert";
import { describe, it } from "node:test";
import { sequenceToSerialType } from "./utils.js";

describe('sequenceToSerialType', () => {
it('should remove nextval default value and set has_auto_increment to true', () => {
const obj1 = {
"fields": [
{
"collection": "test_collection",
"field": "id",
"type": "integer",
"meta": null,
"schema": {
"name": "id",
"table": "test_collection",
"data_type": "integer",
"default_value": "nextval('test_collection_id_seq'::regclass)",
"max_length": null,
"numeric_precision": 32,
"numeric_scale": 0,
"is_nullable": false,
"is_unique": true,
"is_primary_key": true,
"is_generated": false,
"generation_expression": null,
"has_auto_increment": false,
"foreign_key_table": null,
"foreign_key_column": null
}
}
]
};
const obj2 = {
"fields": [
{
"collection": "test_collection",
"field": "id",
"type": "integer",
"meta": null,
"schema": {
"name": "id",
"table": "test_collection",
"data_type": "integer",
"default_value": null,
"max_length": null,
"numeric_precision": 32,
"numeric_scale": 0,
"is_nullable": false,
"is_unique": true,
"is_primary_key": true,
"is_generated": false,
"generation_expression": null,
"has_auto_increment": true,
"foreign_key_table": null,
"foreign_key_column": null
}
}
]
};
assert.deepEqual(sequenceToSerialType(obj1), obj2);
});

it('should return same snapshot if serial type is already used everywhere', () => {
const obj1 = {
"fields": [
{
"collection": "test_collection",
"field": "id",
"type": "string",
"meta": null,
"schema": {
"name": "id",
"table": "test_collection",
"data_type": "integer",
"default_value": "test",
"max_length": null,
"numeric_precision": 32,
"numeric_scale": 0,
"is_nullable": false,
"is_unique": true,
"is_primary_key": true,
"is_generated": false,
"generation_expression": null,
"has_auto_increment": false,
"foreign_key_table": null,
"foreign_key_column": null
}
}
]
};
const obj2 = {
"fields": [
{
"collection": "test_collection",
"field": "id",
"type": "string",
"meta": null,
"schema": {
"name": "id",
"table": "test_collection",
"data_type": "integer",
"default_value": "test",
"max_length": null,
"numeric_precision": 32,
"numeric_scale": 0,
"is_nullable": false,
"is_unique": true,
"is_primary_key": true,
"is_generated": false,
"generation_expression": null,
"has_auto_increment": false,
"foreign_key_table": null,
"foreign_key_column": null
}
}
]
};
assert.deepEqual(sequenceToSerialType(obj1), obj2);
});
});
11 changes: 11 additions & 0 deletions src/dialects/postgres/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function sequenceToSerialType<T extends Record<string, any>>(snapshot: T): T {
snapshot.fields
.map( (field: any) => {
if (field.schema?.default_value=="nextval('"+field.schema?.table+"_"+field.schema?.name+"_seq'::regclass)") {
field.schema.default_value = null;
field.schema.has_auto_increment = true;
}
return field;
}) as T;
return snapshot;
}
2 changes: 2 additions & 0 deletions src/schemaExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { readFile, writeFile } from 'fs/promises';
import { condenseAction } from './condenseAction.js';
import type { IExporter } from './types';
import { ExportHelper } from './utils.js';
import { exportHook } from './schemaExporterHooks.js'

export class SchemaExporter implements IExporter {
private _filePath: string;
Expand Down Expand Up @@ -46,6 +47,7 @@ export class SchemaExporter implements IExporter {
private createAndSaveSnapshot = async () => {
const svc = this._getSchemaService();
let snapshot = await svc.snapshot();
snapshot = exportHook(snapshot);
let hash = svc.getHashedSnapshot(snapshot).hash;
let json = JSON.stringify({ snapshot, hash }, null, 2);
await writeFile(this._filePath, json);
Expand Down
23 changes: 23 additions & 0 deletions src/schemaExporterHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as pgUtils from './dialects/postgres/utils.js';

const modifiers: modifiersType = {
postgres: [pgUtils.sequenceToSerialType]
}

export function exportHook<T extends Record<string, any>>(snapshot: T) {
if (modifiers[snapshot.vendor]?.length)
return modifiers[snapshot.vendor]!.reduce((_snapshot, modifier) => {
return modifier(_snapshot);
}, snapshot)
return snapshot;
};

type modifiersType = Record<string, snapshotFunctionType[]>

type snapshotWithHashType = {
snapshot: Record<string, any>,
hash: string
}

type snapshotWithHashFunctionType = <T extends snapshotWithHashType>(snapshotWithHash: T) => T
type snapshotFunctionType = <T extends Record<string, any>>(snapshotWithHash: T) => T
2 changes: 1 addition & 1 deletion tsconfig.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
"rootDir": "./src",
"outDir": "./dist-test",
},
"include": ["src/utils.ts", "src/utils.test.ts"]
"include": ["src/utils.ts", "src/utils.test.ts", "src/dialects/postgres/utils.ts", "src/dialects/postgres/utils.test.ts"]
}

0 comments on commit 5500975

Please sign in to comment.