Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@athenna/database",
"version": "5.27.0",
"version": "5.28.0",
"description": "The Athenna database handler for SQL/NoSQL.",
"license": "MIT",
"author": "João Lenon <lenon@athenna.io>",
Expand Down
13 changes: 13 additions & 0 deletions src/constants/OriginalSymbol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @athenna/database
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

/**
* Symbol used to store the original value of a model.
*/
export const ORIGINAL_SYMBOL: unique symbol = Symbol('BaseModel.original')
56 changes: 18 additions & 38 deletions src/models/BaseModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
*/

import {
Collection,
Is,
Json,
Options,
String,
Options,
Collection,
type PaginatedResponse,
type PaginationOptions
} from '@athenna/common'
Expand All @@ -21,6 +21,7 @@ import { Database } from '#src/facades/Database'
import type { ModelRelations } from '#src/types'
import { faker, type Faker } from '@faker-js/faker'
import { ModelSchema } from '#src/models/schemas/ModelSchema'
import { ORIGINAL_SYMBOL } from '#src/constants/OriginalSymbol'
import { ModelFactory } from '#src/models/factories/ModelFactory'
import { ModelGenerator } from '#src/models/factories/ModelGenerator'
import { ModelQueryBuilder } from '#src/models/builders/ModelQueryBuilder'
Expand Down Expand Up @@ -435,31 +436,27 @@ export class BaseModel {
* is a fresh instance and is not available in database
* yet.
*/
private original?: Record<string, any>
private [ORIGINAL_SYMBOL]?: Record<string, any>

/**
* Set the original model values by deep copying
* the model state.
*/
public setOriginal() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.original = {}
this[ORIGINAL_SYMBOL] = {}

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Object.keys(Json.copy(Json.omit(this, ['original']))).forEach(key => {
Object.keys(Json.copy(this)).forEach(key => {
const value = this[key]

if (Is.Array(value) && value[0]?.original) {
if (Is.Array(value) && value[0] && ORIGINAL_SYMBOL in value[0]) {
return
}

if (value && value.original) {
if (Is.Object(value) && value && ORIGINAL_SYMBOL in value) {
return
}

this.original[key] = value
this[ORIGINAL_SYMBOL][key] = value
})

return this
Expand All @@ -482,10 +479,6 @@ export class BaseModel {
* Execute the toJSON of relations.
*/
Object.keys(this).forEach(key => {
if (key === 'original') {
return
}

if (relations.includes(key)) {
if (Is.Array(this[key])) {
json[key] = this[key].map(d => (d.toJSON ? d.toJSON() : d))
Expand Down Expand Up @@ -553,12 +546,12 @@ export class BaseModel {
* or if it's a fresh instance.
*/
public isPersisted(): boolean {
return !!this.original
return !!this[ORIGINAL_SYMBOL]
}

/**
* Get values only that are different from
* the original property to avoid updating
* the original symbol to avoid updating
* data that was not changed.
*/
public dirty() {
Expand All @@ -569,33 +562,20 @@ export class BaseModel {
const dirty: Record<string, any> = {}

Object.keys(this).forEach(key => {
if (key === 'original') {
return
}

const delta = Json.diff(this.original[key], this[key])

if (Is.Object(delta)) {
if (!Object.keys(delta).length) {
return
}

dirty[key] = delta
const orig = this[ORIGINAL_SYMBOL][key]
const curr = this[key]

if (Json.isEqual(orig, curr)) {
return
}

if (Is.Array(delta)) {
if (!delta.length) {
return
}

dirty[key] = delta
if (Is.Object(curr) || Is.Array(curr)) {
dirty[key] = Json.copy(curr)

return
}

dirty[key] = delta
dirty[key] = Json.diff(orig, curr)
})

return dirty
Expand Down Expand Up @@ -655,7 +635,7 @@ export class BaseModel {

/**
* Means data is not dirty because there are any
* value that is different from original prop.
* value that is different from original symbol.
*/
if (!Object.keys(data).length) {
return this
Expand Down
4 changes: 2 additions & 2 deletions templates/crud-service-test.edge
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default class {{ crudNamePascal }}ServiceTest {
{{{ createBody }}}
})

assert.containsSubset(data.toJSON(), {{ crudNameLower }}.toJSON())
assert.containSubset(data.toJSON(), {{ crudNameLower }}.toJSON())
}

@Test()
Expand Down Expand Up @@ -77,7 +77,7 @@ export default class {{ crudNamePascal }}ServiceTest {
{{{ updateBody }}}
})

assert.containsSubset(data.toJSON(), {
assert.containSubset(data.toJSON(), {
{{{ updateBody }}}
})
}
Expand Down
50 changes: 25 additions & 25 deletions tests/unit/drivers/MongoDriverTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').findOrFail()

assert.containsSubset(result, data)
assert.containSubset(result, data)
}

@Test()
Expand All @@ -582,7 +582,7 @@ export default class MongoDriverTest {
return { _id: '1', name: 'Marie Curie' }
})

assert.containsSubset(result, data)
assert.containSubset(result, data)
}

@Test()
Expand Down Expand Up @@ -619,7 +619,7 @@ export default class MongoDriverTest {
})
.find()

assert.containsSubset(result, { _id: '1', name: 'Marie Curie' })
assert.containSubset(result, { _id: '1', name: 'Marie Curie' })
}

@Test()
Expand All @@ -629,7 +629,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').find()

assert.containsSubset(result, data)
assert.containSubset(result, data)
}

@Test()
Expand All @@ -656,7 +656,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').findMany()

assert.containsSubset(result, data)
assert.containSubset(result, data)
}

@Test()
Expand All @@ -666,7 +666,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').pluck('name')

assert.containsSubset(result, 'Charles Babbage')
assert.containSubset(result, 'Charles Babbage')
}

@Test()
Expand All @@ -676,7 +676,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').pluckMany('name')

assert.containsSubset(result, ['Charles Babbage'])
assert.containSubset(result, ['Charles Babbage'])
}

@Test()
Expand All @@ -693,7 +693,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').findMany()

assert.containsSubset(result, data)
assert.containSubset(result, data)
}

@Test()
Expand All @@ -710,7 +710,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').paginate()

assert.containsSubset(result.data, data)
assert.containSubset(result.data, data)
assert.deepEqual(result.meta, {
currentPage: 0,
itemCount: 1,
Expand All @@ -733,7 +733,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').paginate(0, 10, '/users')

assert.containsSubset(result.data, data)
assert.containSubset(result.data, data)
assert.deepEqual(result.meta, {
currentPage: 0,
itemCount: 1,
Expand Down Expand Up @@ -762,7 +762,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').create(data)

assert.containsSubset(result, data)
assert.containSubset(result, data)
}

@Test()
Expand All @@ -782,7 +782,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').createMany(data)

assert.containsSubset(result, data)
assert.containSubset(result, data)
}

@Test()
Expand All @@ -799,7 +799,7 @@ export default class MongoDriverTest {

const result = await this.driver.table('users').createOrUpdate(data)

assert.containsSubset(result, data)
assert.containSubset(result, data)
}

@Test()
Expand All @@ -809,7 +809,7 @@ export default class MongoDriverTest {
await this.driver.table('users').create(data)
const result = await this.driver.table('users').createOrUpdate({ ...data, name: 'Robert Kiyosaki Millennials' })

assert.containsSubset(result, { ...data, name: 'Robert Kiyosaki Millennials' })
assert.containSubset(result, { ...data, name: 'Robert Kiyosaki Millennials' })
}

@Test()
Expand All @@ -819,7 +819,7 @@ export default class MongoDriverTest {
await this.driver.table('users').create(data)
const result = await this.driver.table('users').update({ ...data, name: 'Robert Kiyosaki Millennials' })

assert.containsSubset(result, { ...data, name: 'Robert Kiyosaki Millennials' })
assert.containSubset(result, { ...data, name: 'Robert Kiyosaki Millennials' })
}

@Test()
Expand All @@ -835,7 +835,7 @@ export default class MongoDriverTest {
.whereIn('_id', ['1', '2'])
.update({ name: 'Robert Kiyosaki Millennials' })

assert.containsSubset(result, [
assert.containSubset(result, [
{ _id: '1', name: 'Robert Kiyosaki Millennials' },
{ _id: '2', name: 'Robert Kiyosaki Millennials' }
])
Expand Down Expand Up @@ -891,7 +891,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').select('*').where('_id', '1').findMany()

assert.containsSubset(data, [{ _id: '1', name: 'Alan Turing' }])
assert.containSubset(data, [{ _id: '1', name: 'Alan Turing' }])
}

@Test()
Expand Down Expand Up @@ -1258,7 +1258,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').groupBy('_id', 'name').havingNotIn('_id', ['1', '2']).findMany()

assert.containsSubset(data, [{ _id: '3', name: 'Alan Turing' }])
assert.containSubset(data, [{ _id: '3', name: 'Alan Turing' }])
}

@Test()
Expand All @@ -1279,7 +1279,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').groupBy('_id', 'name').havingBetween('_id', ['1', '3']).findMany()

assert.containsSubset(data, [
assert.containSubset(data, [
{ _id: '1', name: 'Robert Kiyosaki' },
{ _id: '2', name: 'Warren Buffet' },
{ _id: '3', name: 'Alan Turing' }
Expand Down Expand Up @@ -1477,7 +1477,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').groupBy('_id', 'name').orHavingNotIn('_id', ['1', '2']).findMany()

assert.containsSubset(data, [{ _id: '3', name: 'Alan Turing' }])
assert.containSubset(data, [{ _id: '3', name: 'Alan Turing' }])
}

@Test()
Expand All @@ -1498,7 +1498,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').groupBy('_id', 'name').orHavingBetween('_id', ['1', '3']).findMany()

assert.containsSubset(data, [
assert.containSubset(data, [
{ _id: '1', name: 'Robert Kiyosaki' },
{ _id: '2', name: 'Warren Buffet' },
{ _id: '3', name: 'Alan Turing' }
Expand Down Expand Up @@ -1801,7 +1801,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').whereNotIn('_id', ['1', '2']).findMany()

assert.containsSubset(data, [{ _id: '3', name: 'Alan Turing' }])
assert.containSubset(data, [{ _id: '3', name: 'Alan Turing' }])
}

@Test()
Expand All @@ -1822,7 +1822,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').whereBetween('_id', ['1', '3']).findMany()

assert.containsSubset(data, [
assert.containSubset(data, [
{ _id: '1', name: 'Robert Kiyosaki' },
{ _id: '2', name: 'Warren Buffet' },
{ _id: '3', name: 'Alan Turing' }
Expand Down Expand Up @@ -2115,7 +2115,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').orWhereNotIn('_id', ['1', '2']).findMany()

assert.containsSubset(data, [{ _id: '3', name: 'Alan Turing' }])
assert.containSubset(data, [{ _id: '3', name: 'Alan Turing' }])
}

@Test()
Expand All @@ -2128,7 +2128,7 @@ export default class MongoDriverTest {

const data = await this.driver.table('users').orWhereBetween('_id', ['1', '3']).findMany()

assert.containsSubset(data, [
assert.containSubset(data, [
{ _id: '1', name: 'Robert Kiyosaki' },
{ _id: '2', name: 'Warren Buffet' },
{ _id: '3', name: 'Alan Turing' }
Expand Down
Loading
Loading