Skip to content

Commit

Permalink
Merge pull request #87 from liam-hq/add_parser_for_schemarb
Browse files Browse the repository at this point in the history
feat: Add parser for schemarb
  • Loading branch information
sasamuku authored Nov 19, 2024
2 parents a2ba299 + 5585547 commit 71ef4cd
Show file tree
Hide file tree
Showing 11 changed files with 2,881 additions and 5 deletions.
7 changes: 6 additions & 1 deletion frontend/packages/db-structure/biome.jsonc
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
"extends": ["../../packages/configs/biome.jsonc"]
"extends": ["../../packages/configs/biome.jsonc"],
"files": {
"ignore": [
"src/parser/schemarb/parser.js" // Because it's generated
]
}
}
9 changes: 7 additions & 2 deletions frontend/packages/db-structure/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@
"lint:biome": "biome check .",
"lint:tsc": "tsc --noEmit",
"fmt": "conc -c auto pnpm:fmt:*",
"fmt:biome": "biome check --write --unsafe ."
"fmt:biome": "biome check --write --unsafe .",
"test": "vitest"
},
"dependencies": {
"lodash.isequal": "^4.5.0",
"lodash.sortby": "^4.7.0",
"pluralize": "^8.0.0",
"valibot": "^1.0.0-beta.5"
},
"devDependencies": {
"@biomejs/biome": "1.9.3",
"@packages/configs": "workspace:*",
"typescript": "^5"
"typescript": "^5",
"vitest": "^2.1.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`parse > should parse schema.rb to JSON correctly 1`] = `
{
"relationships": {},
"tables": {
"xero_users": {
"color": null,
"comment": null,
"fields": [
{
"check": null,
"comment": null,
"default": null,
"increment": false,
"name": "id",
"notNull": false,
"primary": false,
"type": "varchar",
"unique": false,
},
{
"check": null,
"comment": null,
"default": null,
"increment": false,
"name": "email_address",
"notNull": false,
"primary": false,
"type": "string",
"unique": false,
},
],
"indices": [],
"name": "xero_users",
"x": 0,
"y": 0,
},
},
}
`;
16 changes: 16 additions & 0 deletions frontend/packages/db-structure/src/parser/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import fs from 'node:fs'
import path from 'node:path'
import { describe, expect, it } from 'vitest'
import { parse } from '.'

describe(parse, () => {
it('should parse schema.rb to JSON correctly', () => {
const schemaText = fs.readFileSync(
path.resolve(__dirname, './schemarb/input/schema1.in.rb'),
'utf-8',
)

const result = parse(schemaText, 'schemarb')
expect(result).toMatchSnapshot()
})
})
56 changes: 56 additions & 0 deletions frontend/packages/db-structure/src/parser/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { DBStructure, Table } from 'src/schema'
import { schemaRbParser } from './schemarb'

type SupportedFormat = 'schemarb' | 'postgres'

// biome-ignore lint/suspicious/noExplicitAny: TODO: Generate types with pegjs
const convertToDBStructure = (data: any): DBStructure => {
return {
// biome-ignore lint/suspicious/noExplicitAny: TODO: Generate types with pegjs
tables: data.tables.reduce((acc: Record<string, Table>, table: any) => {
acc[table.name] = {
comment: null,
// biome-ignore lint/suspicious/noExplicitAny: TODO: Generate types with pegjs
fields: table.fields.map((field: any) => ({
check: null,
comment: null,
default: null,
increment: false,
name: field.name,
notNull: false,
primary: false,
type: field.type.type_name,
unique: false,
})),
indices: [],
name: table.name,
x: 0,
y: 0,
color: null,
}
return acc
}, {}),
relationships: {},
}
}

// biome-ignore lint/suspicious/noExplicitAny: TODO: Generate types with pegjs
const selectParser = (format: SupportedFormat): any => {
switch (format) {
case 'schemarb':
return schemaRbParser
default:
throw new Error(`Unsupported format: ${format}`)
}
}

export const parse = (str: string, format: SupportedFormat): DBStructure => {
try {
const parser = selectParser(format)
const parsedSchema = parser.parse(str)
const dbStructure = convertToDBStructure(parsedSchema)
return dbStructure
} catch (_error) {
throw new Error('Failed to parse schema')
}
}
3 changes: 3 additions & 0 deletions frontend/packages/db-structure/src/parser/schemarb/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import schemaRbParser from './parser'

export { schemaRbParser }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
create_table "xero_users", id: :uuid, default: -> { "uuid_generate_v4()" }, force: :cascade do |t|
t.string "email_address"
end
Loading

0 comments on commit 71ef4cd

Please sign in to comment.