Skip to content

Commit

Permalink
feat: change static from Convention class for create a new instance a…
Browse files Browse the repository at this point in the history
…lways repository is created
  • Loading branch information
maikvortx committed Jan 3, 2022
1 parent f67b68d commit 17dc9a8
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 154 deletions.
8 changes: 4 additions & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"999999",
"--colors",
"--recursive",
"${workspaceFolder}/test"
"${workspaceFolder}/test/unit"
],
"internalConsoleOptions": "openOnSessionStart",
"skipFiles": [
Expand All @@ -32,7 +32,7 @@
"999999",
"--colors",
"--recursive",
"${workspaceFolder}/testdb/mssql"
"${workspaceFolder}/test/integration/mssql"
],
"internalConsoleOptions": "openOnSessionStart",
"skipFiles": [
Expand All @@ -51,7 +51,7 @@
"999999",
"--colors",
"--recursive",
"${workspaceFolder}/testdb/mysql"
"${workspaceFolder}/test/integration/mysql"
],
"internalConsoleOptions": "openOnSessionStart",
"skipFiles": [
Expand All @@ -70,7 +70,7 @@
"999999",
"--colors",
"--recursive",
"${workspaceFolder}/testdb/pg"
"${workspaceFolder}/test/integration/pg"
],
"internalConsoleOptions": "openOnSessionStart",
"skipFiles": [
Expand Down
28 changes: 13 additions & 15 deletions src/convention.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
module.exports = class Convention {

static camelToSnake(string) {
return string.replace(/([A-Z])/g, "_$1").toLowerCase()
}

static toTableFieldName(entityField) {
return this.camelToSnake(entityField)
}

static isScalarType(type) {
const scalarTypes = [Number, String, Boolean, Date, Object, Array]
return scalarTypes.includes(type)
}

}
camelToSnake (string) {
return string.replace(/([A-Z])/g, '_$1').toLowerCase()
}

toTableFieldName (entityField) {
return this.camelToSnake(entityField)
}

isScalarType (type) {
const scalarTypes = [Number, String, Boolean, Date, Object, Array]
return scalarTypes.includes(type)
}
}
234 changes: 117 additions & 117 deletions src/dataMapper.js
Original file line number Diff line number Diff line change
@@ -1,129 +1,129 @@
const Convention = require('./convention')
const { entity } = require('@herbsjs/gotu')
const dependency = { convention: Convention }

class DataMapper {

constructor(entity, entityIDs = [], foreignKeys = [], options = {}) {
const di = Object.assign({}, dependency, options.injection)
this.convention = di.convention
this.entity = entity
const schema = entity.prototype.meta.schema
this.allFields = DataMapper.buildAllFields(schema, entityIDs, foreignKeys, this.convention)
this._proxy === undefined
}

toEntity(payload) {
if (this._proxy === undefined) this._proxy = this.buildProxy()
this._proxy.load(payload)
return this.entity.fromJSON(this._proxy, { allowExtraKeys: true })
constructor (entity, entityIDs = [], foreignKeys = [], options = {}) {
this.convention = Object.assign(new Convention(), options.convention)
this.entity = entity
const schema = entity.prototype.meta.schema
this.allFields = DataMapper.buildAllFields(
schema,
entityIDs,
foreignKeys,
this.convention
)
this._proxy === undefined
}

toEntity (payload) {
if (this._proxy === undefined) this._proxy = this.buildProxy()
this._proxy.load(payload)
return this.entity.fromJSON(this._proxy, { allowExtraKeys: true })
}

static buildAllFields (schema, entityIDs, foreignKeys, convention) {
function fieldType (type) {
if (Array.isArray(type)) return fieldType(type[0])
return type
}

static buildAllFields(schema, entityIDs, foreignKeys, convention) {

function fieldType(type) {
if (Array.isArray(type)) return fieldType(type[0])
return type
}

const fields = Object.keys(schema)
.map((field) => {
if (typeof schema[field] === 'function') return { type: Function }
const isArray = Array.isArray(schema[field].type)
const type = fieldType(schema[field].type)
const isEntity = entity.isEntity(type)
const nameDb = convention.toTableFieldName(field)
const isID = entityIDs.includes(field)
return { name: field, type, isEntity, nameDb, isArray, isID }
})

const fkFields = foreignKeys.flatMap((fks) => {
return Object.keys(fks).map((field) => {
const isArray = Array.isArray(fks[field])
const type = fieldType(fks[field])
const isEntity = entity.isEntity(type)
const nameDb = convention.toTableFieldName(field)
return { name: field, type, isEntity, nameDb, isArray, isFk: true }
})
})

const allFields = fields.concat(fkFields).filter((f) => f.type !== Function)

return allFields
const fields = Object.keys(schema).map(field => {
if (typeof schema[field] === 'function') return { type: Function }
const isArray = Array.isArray(schema[field].type)
const type = fieldType(schema[field].type)
const isEntity = entity.isEntity(type)
const nameDb = convention.toTableFieldName(field)
const isID = entityIDs.includes(field)
return { name: field, type, isEntity, nameDb, isArray, isID }
})

const fkFields = foreignKeys.flatMap(fks => {
return Object.keys(fks).map(field => {
const isArray = Array.isArray(fks[field])
const type = fieldType(fks[field])
const isEntity = entity.isEntity(type)
const nameDb = convention.toTableFieldName(field)
return { name: field, type, isEntity, nameDb, isArray, isFk: true }
})
})

const allFields = fields.concat(fkFields).filter(f => f.type !== Function)

return allFields
}

toTableFieldName (entityFieldName) {
return this.convention.toTableFieldName(entityFieldName)
}

tableIDs () {
return this.allFields
.filter(i => i.isID)
.map(i => this.convention.toTableFieldName(i.name))
}

tableFields () {
return this.allFields.filter(i => !i.isEntity).map(i => i.nameDb)
}

tableFieldsWithValue (instance) {
return this.allFields
.filter(i => !i.isEntity)
.map(i => ({ [i.nameDb]: instance[i.name] }))
.reduce((x, y) => ({ ...x, ...y }))
}

buildProxy () {
function getDataParser (type, isArray) {
function arrayDataParser (value, parser) {
if (value === null) return null
return value.map(i => parser(i))
}

function dataParser (value, parser) {
if (value === null) return null
return parser(value)
}

if (isArray) {
const parser = getDataParser(type, false)
return value => arrayDataParser(value, parser)
}

if (type === Date || !convention.isScalarType(type)) return x => x

return value => dataParser(value, type)
}

toTableFieldName(entityFieldName) {
return this.convention.toTableFieldName(entityFieldName)
}

tableIDs() {
return this.allFields.filter((i) => i.isID).map(i => this.convention.toTableFieldName(i.name))
}

tableFields() {
return this.allFields
.filter((i) => !i.isEntity)
.map((i) => i.nameDb)
}

tableFieldsWithValue(instance) {
return this.allFields
.filter((i) => !i.isEntity)
.map(i => ({ [i.nameDb]: instance[i.name] }))
.reduce((x, y) => ({ ...x, ...y }))
}

buildProxy() {

function getDataParser(type, isArray) {
function arrayDataParser(value, parser) {
if (value === null) return null
return value.map((i) => parser(i))
}

function dataParser(value, parser) {
if (value === null) return null
return parser(value)
}

if (isArray) {
const parser = getDataParser(type, false)
return (value) => arrayDataParser(value, parser)
}

if ((type === Date) || (!convention.isScalarType(type)))
return (x) => x

return (value) => dataParser(value, type)
}

const convention = this.convention
const proxy = {}

Object.defineProperty(proxy, '_payload', {
enumerable: false,
writable: true,
value: null
})

Object.defineProperty(proxy, 'load', {
enumerable: false,
value: function load(payload) { this._payload = payload },
})

for (const field of this.allFields) {
const parser = getDataParser(field.type, field.isArray)
const nameDb = field.nameDb
Object.defineProperty(proxy, field.name, {
enumerable: true,
get: function () {
if (field.isEntity) return undefined
return parser(this._payload[nameDb])
}
})
const convention = this.convention
const proxy = {}

Object.defineProperty(proxy, '_payload', {
enumerable: false,
writable: true,
value: null
})

Object.defineProperty(proxy, 'load', {
enumerable: false,
value: function load (payload) {
this._payload = payload
}
})

for (const field of this.allFields) {
const parser = getDataParser(field.type, field.isArray)
const nameDb = field.nameDb
Object.defineProperty(proxy, field.name, {
enumerable: true,
get: function () {
if (field.isEntity) return undefined
return parser(this._payload[nameDb])
}
return proxy
})
}
return proxy
}
}

module.exports = DataMapper
module.exports = DataMapper
6 changes: 2 additions & 4 deletions src/repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ const Convention = require('./convention')
const DataMapper = require('./dataMapper')
const { checker } = require('@herbsjs/suma')

const dependency = { convention: Convention }

module.exports = class Repository {
constructor (options) {
this.convention = Object.assign(dependency.convention, options.convention)
constructor (options) {
this.convention = Object.assign(new Convention(), options.convention)
this.table = options.table
this.schema = options.schema
this.tableQualifiedName = this.schema
Expand Down
2 changes: 1 addition & 1 deletion test/integration/pg/convention.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const connection = require('../connection')
const assert = require('assert')
const { camelCase } = require('lodash')

describe.only('Query Find with Conventions', () => {
describe('Query Find with Conventions', () => {
const table = 'testRepository'
const schema = 'herbs2knex_testdb'

Expand Down
3 changes: 2 additions & 1 deletion test/unit/convention.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ describe('Convetion', () => {
it('entity field name to database field name', () => {
//given
const entityField = "fieldName"
const convention = new Convetion()
//when
const dbField = Convetion.toTableFieldName(entityField)
const dbField = convention.toTableFieldName(entityField)
//then
assert.deepStrictEqual(dbField, "field_name")
})
Expand Down
Loading

0 comments on commit 17dc9a8

Please sign in to comment.