fix: Исправил ошибку установки внутреного айди для записи при создании сущности

This commit is contained in:
Nikita Dezzpil Orlov 2022-01-31 17:38:53 +03:00
parent 79cdca410e
commit 41aa5d951a
4 changed files with 115 additions and 6 deletions

35
src/app/repo/sqlite.ts Normal file
View File

@ -0,0 +1,35 @@
import { Entity } from '../entity'
import { ErrEntityNotFound, ErrFoundNotUniqEntity, Repo } from '../repo'
import { StorageSQLite } from '../storage/sqlite'
export abstract class RepoSQLite<T extends Entity<any>> extends Repo<T> {
abstract Create(): Promise<void>
async Drop(): Promise<void> {
const st = this._storage as StorageSQLite
await st?.db?.run(`DROP TABLE IF EXISTS ${this.Name()}`)
}
async Recreate(): Promise<void> {
await this.Drop()
await this.Create()
}
async findById(id: string): Promise<T> {
const uniqKey = this.Entity().data.uniqKey()
const cond = `${uniqKey} = ?`
const cursor = await this._storage.find(this.Name(), { [cond]: [id] })
const entryList = await cursor.toArray()
if (entryList.length > 1) {
throw new ErrFoundNotUniqEntity(
`found few (${entryList.length}) entries in ${this.Name()} for id ${id}`
)
}
if (entryList.length === 0) {
throw new ErrEntityNotFound(`not found entry in [${this.Name()}] for id [${id}]`)
}
return this._transformer(entryList[0])
}
}

View File

@ -156,7 +156,7 @@ export class SQLiteCursor implements StorageCursor {
}
_buildSQL(): { query: string[]; params: (string | number)[] } {
const query = [`SELECT * FROM ${this._tableName}`]
const query = [`SELECT ROWID as '_id', * FROM ${this._tableName}`]
const { where, params } = parseCriteria(this._criteria)
if (where) {
query.push(`WHERE ${where}`)

View File

@ -21,12 +21,12 @@ class Item extends Entity<ItemData> {
return this._data.c
}
_getRepo(storage: Storage): ItemRepository {
return new ItemRepository(storage)
_getRepo(storage: Storage): ItemRepo {
return new ItemRepo(storage)
}
}
class ItemRepository extends Repo<Item> {
class ItemRepo extends Repo<Item> {
Name() {
return 'items'
}
@ -36,10 +36,10 @@ class ItemRepository extends Repo<Item> {
}
}
describe('ItemRepository', () => {
describe('ItemRepo', () => {
describe('map storage save', () => {
const storage = new MapStorage('')
const repo = new ItemRepository(storage)
const repo = new ItemRepo(storage)
it('should return entity', async () => {
const dt = Data.assign(new ItemData(), { a: 1, b: 2, c: { d: 3 } })

View File

@ -0,0 +1,74 @@
import { Data } from '../../app/data'
import { Entity } from '../../app/entity'
import { Storage } from '../../app/storage'
import { Repo } from '../../app/repo'
import { RepoSQLite } from '../../app/repo/sqlite'
import { StorageSQLite } from '../../app/storage/sqlite'
import { assert } from 'chai'
class ItemData extends Data {
uniqKey(): string {
return 'uid'
}
uid: string
title: string
}
class ItemEntity extends Entity<ItemData> {
_getRepo(storage: Storage): Repo<Entity<ItemData>> {
return undefined
}
_getVO(): ItemData {
return new ItemData()
}
}
class ItemsRepo extends RepoSQLite<ItemEntity> {
Entity(): ItemEntity {
return new ItemEntity()
}
Name(): string {
return 'items'
}
async Create(): Promise<void> {
const st = this._storage as StorageSQLite
await st?.db?.run(`
create table if not exists ${this.Name()} (
uid varchar(255) not null unique,
title text null
)
`)
}
}
describe('ItemsRepoSQLite', () => {
const dsn = __dirname + `/sqlite.test.db`
let storage: StorageSQLite
let repo: ItemsRepo
beforeAll(async () => {
storage = new StorageSQLite({ dsn })
await storage.connect()
storage.db.on('trace', (data: string) => {
console.log(data)
})
repo = new ItemsRepo(storage)
await repo.Recreate()
for (const uid of ['foo', 'bar', 'pew', 'baz', 'fox']) {
const d = new ItemData()
d.uid = uid
const e = new ItemEntity(d)
await repo.save(e)
}
})
describe('#findById', () => {
it('should return persisted entity', async () => {
const e = await repo.findById('foo')
assert.isTrue(e.isPersisted())
assert.isDefined(e._id)
})
})
})