Compare commits
12
Commits
v1.1.2
..
bcefbb7425
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcefbb7425 | ||
|
|
e1d03577dd | ||
|
|
231895c7cd | ||
|
|
e282a887c3 | ||
|
|
14a46a71b3 | ||
|
|
ead279ca5d | ||
|
|
50261ac29e | ||
|
|
017f735613 | ||
|
|
8e619112cd | ||
|
|
d0942e59d9 | ||
|
|
3b6e00ec1d | ||
|
|
d92396967a |
No files matched your search
+42
@@ -2,6 +2,48 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [1.3.3](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.3.2...v1.3.3) (2021-10-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Потерялась зависимость rfdc ([e1d0357](https://git.archive.systems/Dezzpil/ivanovna.orm/commit/e1d03577dd973c6e651a8d175fbabcf5a8c1fd53))
|
||||
|
||||
### [1.3.2](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.3.1...v1.3.2) (2021-10-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* трансформер доступен для дочерних классов ([e282a88](https://git.archive.systems/Dezzpil/ivanovna.orm/commit/e282a887c3e8c5fc6d159da9881f13adb2f527b4))
|
||||
|
||||
### [1.3.1](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.3.0...v1.3.1) (2021-10-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* обновил API типов ([ead279c](https://git.archive.systems/Dezzpil/ivanovna.orm/commit/ead279ca5dbcc391aa30b224195295a4d1f81684))
|
||||
|
||||
## [1.3.0](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.2.0...v1.3.0) (2021-10-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* добавил управление трансформацией данных для репозитория ([017f735](https://git.archive.systems/Dezzpil/ivanovna.orm/commit/017f7356134c306c9ba46b19385c3e96444c613b))
|
||||
|
||||
## [1.2.0](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.1.3...v1.2.0) (2021-10-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* добавил Entity Manager ([d0942e5](https://git.archive.systems/Dezzpil/ivanovna.orm/commit/d0942e59d97d861aa3368ee96a3a15f0418263e4))
|
||||
|
||||
### [1.1.3](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.1.2...v1.1.3) (2021-10-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* путь к файлу типов ([d923969](https://git.archive.systems/Dezzpil/ivanovna.orm/commit/d92396967a79b51fe63d6620eb8b2169260f4ec7))
|
||||
|
||||
### [1.1.2](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.1.1...v1.1.2) (2021-09-30)
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/** @public */
|
||||
export declare abstract class Data {
|
||||
[key: string]: any;
|
||||
/**
|
||||
* @deprecated use fromObject()
|
||||
*/
|
||||
static assign(vo: Data, values: ValuesObject): Data;
|
||||
set(key: string, value: any): void;
|
||||
fromObject(object: ValuesObject): void;
|
||||
toObject(exclude?: string[]): Record<string, any>;
|
||||
toObject(exclude?: string[]): ValuesObject;
|
||||
abstract uniqKey(): string;
|
||||
}
|
||||
|
||||
@@ -26,6 +29,20 @@ export declare abstract class Entity<T extends Data> {
|
||||
/** @public */
|
||||
export declare type EntityConstructor<T extends Data> = new (data?: T) => Entity<T>;
|
||||
|
||||
/** @public */
|
||||
export declare class EntityManager {
|
||||
private readonly _storage;
|
||||
private _saveMap;
|
||||
private _removeMap;
|
||||
constructor(storage: Storage_2);
|
||||
persist(entity: Entity<any>): this;
|
||||
persistMany(entities: Entity<any>[]): this;
|
||||
remove(entity: Entity<any>): this;
|
||||
forget(): this;
|
||||
flush(): Promise<this>;
|
||||
refresh(entity: Entity<any>): Promise<Entity<any>>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export declare class ErrEntityHasNoUniqKeyValue extends Error {
|
||||
}
|
||||
@@ -52,6 +69,7 @@ export declare abstract class Repo<T extends Entity<any>> {
|
||||
protected _entity: T;
|
||||
protected _limit: number;
|
||||
protected _offset: number;
|
||||
protected _transformer: (obj: any) => any;
|
||||
/**
|
||||
* Возвращает объект соотв. сущности, например new App()
|
||||
*/
|
||||
@@ -60,9 +78,8 @@ export declare abstract class Repo<T extends Entity<any>> {
|
||||
* Возвращает название коллекции/таблицы/... хранящей записи соотв. сущностей
|
||||
*/
|
||||
abstract Name(): string;
|
||||
_transformer: (object: any) => any;
|
||||
constructor(storage: Storage_2);
|
||||
resetTransformer(): void;
|
||||
constructor(storage: Storage_2, transformer?: (obj: any) => any);
|
||||
setTransformer(transformer?: (obj: any) => any): this;
|
||||
get storage(): Storage_2;
|
||||
save(entity: T): Promise<this>;
|
||||
findById(id: string): Promise<T | null>;
|
||||
@@ -85,13 +102,13 @@ declare abstract class Storage_2 {
|
||||
abstract save(name: string, uniqKey: string, data: Record<string, any>): Promise<string>;
|
||||
abstract createSession(): StorageSession;
|
||||
abstract count(name: string, query?: Record<string, any>): Promise<number>;
|
||||
abstract remove(collectionName: string, uniqKeyName: string, uniqKey: string): Promise<boolean>;
|
||||
abstract remove(name: string, uniqKey: string, uniqVal: string | number): Promise<boolean>;
|
||||
}
|
||||
export { Storage_2 as Storage }
|
||||
|
||||
/** @public */
|
||||
export declare interface StorageCursor {
|
||||
limit(number_: number): StorageCursor;
|
||||
limit(number: number): StorageCursor;
|
||||
sort(parameters: Record<string, any>): StorageCursor;
|
||||
skip(offset: number): StorageCursor;
|
||||
toArray(): Promise<any[]>;
|
||||
|
||||
Generated
+7
-7
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "ivna-orm",
|
||||
"version": "1.1.2",
|
||||
"version": "1.3.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ivna-orm",
|
||||
"version": "1.1.2",
|
||||
"version": "1.3.3",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"rfdc": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jest/test-sequencer": "^27.2.3",
|
||||
"@microsoft/api-extractor": "^7.18.11",
|
||||
@@ -21,7 +24,6 @@
|
||||
"jest-teamcity": "^1.10.0",
|
||||
"nanoid": "^3.1.28",
|
||||
"prettier": "^2.4.1",
|
||||
"rfdc": "^1.3.0",
|
||||
"standard-version": "^9.3.1",
|
||||
"ts-jest": "^27.0.5",
|
||||
"ts-node": "^10.2.1",
|
||||
@@ -5658,8 +5660,7 @@
|
||||
"node_modules/rfdc": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
|
||||
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
@@ -11393,8 +11394,7 @@
|
||||
"rfdc": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
|
||||
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "3.0.2",
|
||||
|
||||
+5
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ivna-orm",
|
||||
"version": "1.1.2",
|
||||
"version": "1.3.3",
|
||||
"description": "Mini ORM for convenience",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
@@ -11,7 +11,7 @@
|
||||
"src/app/**/*",
|
||||
"orm.d.ts"
|
||||
],
|
||||
"types": "dist/index.d.ts",
|
||||
"types": "orm.d.ts",
|
||||
"scripts": {
|
||||
"test": "node --no-warnings node_modules/.bin/jest --runInBand --forceExit",
|
||||
"build": "rimraf dist && tsc -b -v",
|
||||
@@ -43,7 +43,6 @@
|
||||
"jest-teamcity": "^1.10.0",
|
||||
"nanoid": "^3.1.28",
|
||||
"prettier": "^2.4.1",
|
||||
"rfdc": "^1.3.0",
|
||||
"standard-version": "^9.3.1",
|
||||
"ts-jest": "^27.0.5",
|
||||
"ts-node": "^10.2.1",
|
||||
@@ -60,5 +59,8 @@
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"tabWidth": 4
|
||||
},
|
||||
"dependencies": {
|
||||
"rfdc": "^1.3.0"
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -7,6 +7,9 @@ export type ValuesObject = Record<string, any>
|
||||
export abstract class Data {
|
||||
[key: string]: any
|
||||
|
||||
/**
|
||||
* @deprecated use fromObject()
|
||||
*/
|
||||
static assign(vo: Data, values: ValuesObject): Data {
|
||||
for (const key of Object.getOwnPropertyNames(values)) {
|
||||
vo[key] = values[key]
|
||||
@@ -26,7 +29,7 @@ export abstract class Data {
|
||||
}
|
||||
}
|
||||
|
||||
toObject(exclude: string[] = []): Record<string, any> {
|
||||
toObject(exclude: string[] = []): ValuesObject {
|
||||
const object = {} as ValuesObject
|
||||
for (const key of Object.getOwnPropertyNames(this)) {
|
||||
if (key.startsWith('__')) {
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Entity } from '../entity'
|
||||
import { Storage } from '../storage'
|
||||
|
||||
/** @public */
|
||||
export class EntityManager {
|
||||
private readonly _storage: Storage
|
||||
private _saveMap: Map<string, Entity<any>>
|
||||
private _removeMap: Map<string, Entity<any>>
|
||||
|
||||
constructor(storage: Storage) {
|
||||
this._storage = storage
|
||||
this._saveMap = new Map()
|
||||
this._removeMap = new Map()
|
||||
}
|
||||
|
||||
persist(entity: Entity<any>): this {
|
||||
const key = [entity.constructor.name, entity.getUniqKey()].join('&')
|
||||
this._saveMap.set(key, entity)
|
||||
return this
|
||||
}
|
||||
|
||||
persistMany(entities: Entity<any>[]): this {
|
||||
for (let entity of entities) {
|
||||
this.persist(entity)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
remove(entity: Entity<any>): this {
|
||||
const key = [entity.constructor.name, entity.getUniqKey()].join('&')
|
||||
this._removeMap.set(key, entity)
|
||||
return this
|
||||
}
|
||||
|
||||
forget(): this {
|
||||
this._saveMap = new Map()
|
||||
return this
|
||||
}
|
||||
|
||||
async flush() {
|
||||
if (!this._saveMap.size && !this._removeMap.size) return this
|
||||
|
||||
const session = this._storage.createSession()
|
||||
await session.start()
|
||||
await session.commit(async () => {
|
||||
for (let en of this._saveMap.values()) {
|
||||
await en._getRepo(this._storage).save(en)
|
||||
}
|
||||
this._saveMap = new Map()
|
||||
|
||||
for (let en of this._removeMap.values()) {
|
||||
await en._getRepo(this._storage).remove(en)
|
||||
}
|
||||
this._removeMap = new Map()
|
||||
})
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
async refresh(entity: Entity<any>) {
|
||||
const repo = entity._getRepo(this._storage)
|
||||
return repo.findById(entity.getUniqKey())
|
||||
}
|
||||
}
|
||||
+10
-5
@@ -15,6 +15,8 @@ export abstract class Repo<T extends Entity<any>> {
|
||||
protected _limit = 0
|
||||
protected _offset = 0
|
||||
|
||||
protected _transformer: (obj: any) => any
|
||||
|
||||
/**
|
||||
* Возвращает объект соотв. сущности, например new App()
|
||||
*/
|
||||
@@ -25,15 +27,16 @@ export abstract class Repo<T extends Entity<any>> {
|
||||
*/
|
||||
abstract Name(): string
|
||||
|
||||
_transformer: (object: any) => any
|
||||
|
||||
constructor(storage: Storage) {
|
||||
constructor(storage: Storage, transformer?: (obj: any) => any) {
|
||||
this._storage = storage
|
||||
this._entity = this.Entity()
|
||||
this.resetTransformer()
|
||||
this.setTransformer(transformer)
|
||||
}
|
||||
|
||||
resetTransformer() {
|
||||
setTransformer(transformer?: (obj: any) => any): this {
|
||||
if (transformer) {
|
||||
this._transformer = transformer
|
||||
} else {
|
||||
this._transformer = function (object: any): any {
|
||||
const entity = this.Entity()
|
||||
entity.data.fromObject(object)
|
||||
@@ -41,6 +44,8 @@ export abstract class Repo<T extends Entity<any>> {
|
||||
return entity
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
get storage(): Storage {
|
||||
return this._storage
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/** @public */
|
||||
export interface StorageCursor {
|
||||
limit(number_: number): StorageCursor
|
||||
limit(number: number): StorageCursor
|
||||
sort(parameters: Record<string, any>): StorageCursor
|
||||
skip(offset: number): StorageCursor
|
||||
toArray(): Promise<any[]>
|
||||
@@ -28,7 +28,7 @@ export abstract class Storage {
|
||||
|
||||
abstract count(name: string, query?: Record<string, any>): Promise<number>
|
||||
|
||||
abstract remove(collectionName: string, uniqKeyName: string, uniqKey: string): Promise<boolean>
|
||||
abstract remove(name: string, uniqKey: string, uniqVal: string | number): Promise<boolean>
|
||||
}
|
||||
|
||||
/** @public */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ClientSession, MongoClient, TransactionOptions } from 'mongodb'
|
||||
import { Storage, StorageCursor, StorageSession } from '../storage'
|
||||
import { ErrStorage, Storage, StorageCursor, StorageSession } from '../storage'
|
||||
import { ErrEntityHasNoUniqKeyValue } from '../entity'
|
||||
|
||||
/** @public */
|
||||
@@ -36,8 +36,8 @@ export class MongoStorage extends Storage {
|
||||
async save(collectionName: string, uniqKey: string, data: Record<string, any>): Promise<string> {
|
||||
await this._connect()
|
||||
const id = data[uniqKey]
|
||||
const coll = await this._client.db().collection(collectionName)
|
||||
if (id !== null && id !== undefined) {
|
||||
const coll = await this._client.db().collection(collectionName)
|
||||
const filter = { [uniqKey]: id }
|
||||
const result = await coll.findOneAndReplace(filter, data, { upsert: true })
|
||||
if (result.lastErrorObject) {
|
||||
@@ -48,7 +48,7 @@ export class MongoStorage extends Storage {
|
||||
return result.lastErrorObject.upserted
|
||||
}
|
||||
|
||||
throw new TypeError(`can not save data to ${collectionName} with result ${result}`)
|
||||
throw new ErrStorage(`can not save data to ${collectionName} with result ${result}`)
|
||||
} else {
|
||||
// Нельзя сохранить сущность без значения уникального ключа
|
||||
// const result = await coll.insertOne(data)
|
||||
@@ -70,8 +70,8 @@ export class MongoStorage extends Storage {
|
||||
return this._client
|
||||
}
|
||||
|
||||
async remove(collectionName: string, uniqKeyName: string, uniqKey: string): Promise<boolean> {
|
||||
const coll = await this._client.db().collection(collectionName)
|
||||
async remove(name: string, uniqKeyName: string, uniqKey: string): Promise<boolean> {
|
||||
const coll = await this._client.db().collection(name)
|
||||
const result = await coll.deleteOne({ [uniqKeyName]: uniqKey })
|
||||
return Promise.resolve(result.acknowledged)
|
||||
}
|
||||
|
||||
@@ -6,3 +6,4 @@ export { Data, ValuesObject } from './app/data'
|
||||
export { Entity, EntityConstructor, ErrEntityHasNoUniqKeyValue } from './app/entity'
|
||||
export { Repo, ErrFoundNotUniqEntity, ErrEntityNotFound } from './app/repo'
|
||||
export { Storage, StorageCursor, ErrStorage, ErrNoSession, StorageSession } from './app/storage'
|
||||
export { EntityManager } from './app/entity/manager'
|
||||
@@ -9,8 +9,8 @@ export class MapCursor implements StorageCursor {
|
||||
this._map = map
|
||||
}
|
||||
|
||||
limit(number_: number): StorageCursor {
|
||||
this._limit = number_
|
||||
limit(number: number): StorageCursor {
|
||||
this._limit = number
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ export class MapStorage extends Storage {
|
||||
return Promise.resolve(0)
|
||||
}
|
||||
|
||||
async remove(collectionName: string, uniqKeyName: string, uniqKey: string): Promise<boolean> {
|
||||
async remove(name: string, uniqKeyName: string, uniqKey: string): Promise<boolean> {
|
||||
return Promise.resolve(true)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user