Skip to content

Commit

Permalink
Merge pull request #105 from liam-hq/enhance-postgres-parser-test
Browse files Browse the repository at this point in the history
Enhance postgres parser test
  • Loading branch information
FunamaYukina authored Nov 28, 2024
2 parents a5d98eb + 35d1414 commit 882f063
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,52 @@ exports[`parse > should parse postgresql to JSON correctly 1`] = `
"relationships": {},
"tables": {
"users": {
"columns": {},
"columns": {
"created_at": {
"check": null,
"comment": null,
"default": null,
"increment": false,
"name": "created_at",
"notNull": false,
"primary": false,
"type": "timestamp",
"unique": false,
},
"email": {
"check": null,
"comment": null,
"default": null,
"increment": false,
"name": "email",
"notNull": true,
"primary": false,
"type": "varchar",
"unique": true,
},
"id": {
"check": null,
"comment": null,
"default": null,
"increment": false,
"name": "id",
"notNull": true,
"primary": true,
"type": "serial",
"unique": false,
},
"username": {
"check": null,
"comment": null,
"default": null,
"increment": false,
"name": "username",
"notNull": true,
"primary": false,
"type": "varchar",
"unique": true,
},
},
"comment": null,
"indices": [],
"name": "users",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import type {
ColumnDef,
Constraint,
CreateStmt,
Node,
String as PgString,
} from '@pgsql/types'
import type { Constraint, CreateStmt, Node } from '@pgsql/types'
import type { Columns, DBStructure, Table } from 'src/schema'
import type { RawStmtWrapper } from './parser'

// Transform function for AST to DBStructure
export const convertToDBStructure = (ast: RawStmtWrapper[]): DBStructure => {
const tables: Record<string, Table> = {}

// Creating a new variable str to hold the returned string value,
// as it's not a property of the String type.
interface PgString {
sval: string
str: string
}

function isStringNode(node: Node): node is { String: PgString } {
return (node as { String: { str: string } }).String !== undefined
return (
'String' in node &&
typeof node.String === 'object' &&
node.String !== null &&
'str' in node.String &&
node.String.str !== 'pg_catalog'
)
}

function isConstraintNode(node: Node): node is { Constraint: Constraint } {
Expand All @@ -40,21 +47,18 @@ export const convertToDBStructure = (ast: RawStmtWrapper[]): DBStructure => {

const tableName = createStmt.relation.relname
const columns: Columns = {}
createStmt.tableElts
.filter(
(elt: Node): elt is { ColumnDef: ColumnDef } => 'ColumnDef' in elt,
)
.map((elt) => {
for (const elt of createStmt.tableElts) {
if ('ColumnDef' in elt) {
const colDef = elt.ColumnDef
return {
columns[colDef.colname || ''] = {
name: colDef.colname || '',
type:
colDef.typeName?.names
?.filter(isStringNode)
.map((n) => n.String.sval)
.join(' ') || '',
default: '', // TODO
check: '', // TODO
.map((n) => n.String.str)
.join('') || '',
default: null, // TODO
check: null, // TODO
primary:
colDef.constraints
?.filter(isConstraintNode)
Expand All @@ -77,9 +81,10 @@ export const convertToDBStructure = (ast: RawStmtWrapper[]): DBStructure => {
colDef.typeName?.names
?.filter(isStringNode)
.some((n) => n.String.sval === 'serial') || false,
comment: '', // TODO
comment: null, // TODO
}
})
}
}

if (tableName) {
tables[tableName] = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type { Table } from 'src/schema'
import { aColumn, aDBStructure, aTable } from 'src/schema/factories'
import { describe, expect, it } from 'vitest'
import { processor } from '.'

describe(processor, () => {
describe('should parse create_table correctry', () => {
const userTable = (override?: Partial<Table>) =>
aDBStructure({
tables: {
users: aTable({
name: 'users',
columns: {
id: aColumn({
name: 'id',
type: 'serial',
notNull: true,
primary: true,
}),
...override?.columns,
},
}),
},
})

it('not null', () => {
const result = processor(/* PostgreSQL */ `
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
`)

const expected = userTable({
columns: {
name: aColumn({
name: 'name',
type: 'varchar',
notNull: true,
}),
},
})

expect(result).toEqual(expected)
})

it('nullable', () => {
const result = processor(/* PostgreSQL */ `
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255)
);
`)

const expected = userTable({
columns: {
name: aColumn({
name: 'name',
type: 'varchar',
notNull: false,
}),
},
})

expect(result).toEqual(expected)
})

// TODO: Implement default value
})
})

0 comments on commit 882f063

Please sign in to comment.