10 Commits
9 changed files with 156 additions and 37 deletions

No files matched your search

+35
View File
@@ -2,6 +2,41 @@
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. 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.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)
### Bug Fixes
* заменил все unknow на any ([20a969c](https://git.archive.systems/Dezzpil/ivanovna.orm/commit/20a969c829d5d4d9ec5b4f001f6d13be3570a97d))
### [1.1.1](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.1.0...v1.1.1) (2021-09-29) ### [1.1.1](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.1.0...v1.1.1) (2021-09-29)
## [1.1.0](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.0.2...v1.1.0) (2021-09-29) ## [1.1.0](https://git.archive.systems/Dezzpil/ivanovna.orm/compare/v1.0.2...v1.1.0) (2021-09-29)
Vendored
+25 -11
View File
@@ -26,6 +26,20 @@ export declare abstract class Entity<T extends Data> {
/** @public */ /** @public */
export declare type EntityConstructor<T extends Data> = new (data?: T) => Entity<T>; 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 */ /** @public */
export declare class ErrEntityHasNoUniqKeyValue extends Error { export declare class ErrEntityHasNoUniqKeyValue extends Error {
} }
@@ -52,6 +66,7 @@ export declare abstract class Repo<T extends Entity<any>> {
protected _entity: T; protected _entity: T;
protected _limit: number; protected _limit: number;
protected _offset: number; protected _offset: number;
private _transformer;
/** /**
* Возвращает объект соотв. сущности, например new App() * Возвращает объект соотв. сущности, например new App()
*/ */
@@ -60,9 +75,8 @@ export declare abstract class Repo<T extends Entity<any>> {
* Возвращает название коллекции/таблицы/... хранящей записи соотв. сущностей * Возвращает название коллекции/таблицы/... хранящей записи соотв. сущностей
*/ */
abstract Name(): string; abstract Name(): string;
_transformer: (object: any) => any; constructor(storage: Storage_2, transformer?: (obj: any) => any);
constructor(storage: Storage_2); setTransformer(transformer?: (obj: any) => any): this;
resetTransformer(): void;
get storage(): Storage_2; get storage(): Storage_2;
save(entity: T): Promise<this>; save(entity: T): Promise<this>;
findById(id: string): Promise<T | null>; findById(id: string): Promise<T | null>;
@@ -70,10 +84,10 @@ export declare abstract class Repo<T extends Entity<any>> {
* *
* @protected * @protected
*/ */
_findByParams(parameters: Record<string, unknown>, limit?: number, order?: Record<string, unknown>): Promise<T[]>; _findByParams(parameters: Record<string, any>, limit?: number, order?: Record<string, any>): Promise<T[]>;
findMany(parameters: Record<string, unknown>, order?: Record<string, unknown>): Promise<T[]>; findMany(parameters: Record<string, any>, order?: Record<string, any>): Promise<T[]>;
shift(limit?: number, offset?: number): this; shift(limit?: number, offset?: number): this;
count(query?: Record<string, unknown>): Promise<number>; count(query?: Record<string, any>): Promise<number>;
remove(entity: T, silent?: boolean): Promise<this>; remove(entity: T, silent?: boolean): Promise<this>;
} }
@@ -81,10 +95,10 @@ export declare abstract class Repo<T extends Entity<any>> {
declare abstract class Storage_2 { declare abstract class Storage_2 {
protected _dsn: string; protected _dsn: string;
constructor(dsn: string); constructor(dsn: string);
abstract find(name: string, query: Record<string, unknown>): Promise<StorageCursor>; abstract find(name: string, query: Record<string, any>): Promise<StorageCursor>;
abstract save(name: string, uniqKey: string, data: Record<string, unknown>): Promise<string>; abstract save(name: string, uniqKey: string, data: Record<string, any>): Promise<string>;
abstract createSession(): StorageSession; abstract createSession(): StorageSession;
abstract count(name: string, query?: Record<string, unknown>): Promise<number>; abstract count(name: string, query?: Record<string, any>): Promise<number>;
abstract remove(collectionName: string, uniqKeyName: string, uniqKey: string): Promise<boolean>; abstract remove(collectionName: string, uniqKeyName: string, uniqKey: string): Promise<boolean>;
} }
export { Storage_2 as Storage } export { Storage_2 as Storage }
@@ -99,8 +113,8 @@ export declare interface StorageCursor {
/** @public */ /** @public */
export declare abstract class StorageSession { export declare abstract class StorageSession {
abstract start(options?: Record<string, unknown>): Promise<void>; abstract start(options?: Record<string, any>): Promise<void>;
abstract commit(fn: () => any, options?: Record<string, unknown>): Promise<void>; abstract commit(fn: () => any, options?: Record<string, any>): Promise<void>;
} }
/** @public */ /** @public */
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "ivna-orm", "name": "ivna-orm",
"version": "1.1.1", "version": "1.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ivna-orm", "name": "ivna-orm",
"version": "1.1.1", "version": "1.3.1",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@jest/test-sequencer": "^27.2.3", "@jest/test-sequencer": "^27.2.3",
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "ivna-orm", "name": "ivna-orm",
"version": "1.1.1", "version": "1.3.1",
"description": "Mini ORM for convenience", "description": "Mini ORM for convenience",
"main": "dist/index.js", "main": "dist/index.js",
"files": [ "files": [
@@ -11,7 +11,7 @@
"src/app/**/*", "src/app/**/*",
"orm.d.ts" "orm.d.ts"
], ],
"types": "dist/index.d.ts", "types": "orm.d.ts",
"scripts": { "scripts": {
"test": "node --no-warnings node_modules/.bin/jest --runInBand --forceExit", "test": "node --no-warnings node_modules/.bin/jest --runInBand --forceExit",
"build": "rimraf dist && tsc -b -v", "build": "rimraf dist && tsc -b -v",
+64
View File
@@ -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())
}
}
+19 -14
View File
@@ -15,6 +15,8 @@ export abstract class Repo<T extends Entity<any>> {
protected _limit = 0 protected _limit = 0
protected _offset = 0 protected _offset = 0
private _transformer: (obj: any) => any
/** /**
* Возвращает объект соотв. сущности, например new App() * Возвращает объект соотв. сущности, например new App()
*/ */
@@ -25,21 +27,24 @@ export abstract class Repo<T extends Entity<any>> {
*/ */
abstract Name(): string abstract Name(): string
_transformer: (object: any) => any constructor(storage: Storage, transformer?: (obj: any) => any) {
constructor(storage: Storage) {
this._storage = storage this._storage = storage
this._entity = this.Entity() this._entity = this.Entity()
this.resetTransformer() this.setTransformer(transformer)
} }
resetTransformer() { setTransformer(transformer?: (obj: any) => any): this {
this._transformer = function (object: any): any { if (transformer) {
const entity = this.Entity() this._transformer = transformer
entity.data.fromObject(object) } else {
entity._id = object._id this._transformer = function (object: any): any {
return entity const entity = this.Entity()
entity.data.fromObject(object)
entity._id = object._id
return entity
}
} }
return this
} }
get storage(): Storage { get storage(): Storage {
@@ -74,9 +79,9 @@ export abstract class Repo<T extends Entity<any>> {
* @protected * @protected
*/ */
async _findByParams( async _findByParams(
parameters: Record<string, unknown>, parameters: Record<string, any>,
limit?: number, limit?: number,
order?: Record<string, unknown> order?: Record<string, any>
): Promise<T[]> { ): Promise<T[]> {
const cursor = await this._storage.find(this.Name(), parameters) const cursor = await this._storage.find(this.Name(), parameters)
if (limit && limit > 0) await cursor.limit(limit) if (limit && limit > 0) await cursor.limit(limit)
@@ -90,7 +95,7 @@ export abstract class Repo<T extends Entity<any>> {
return list return list
} }
async findMany(parameters: Record<string, unknown>, order?: Record<string, unknown>): Promise<T[]> { async findMany(parameters: Record<string, any>, order?: Record<string, any>): Promise<T[]> {
const cursor = await this._storage.find(this.Name(), parameters) const cursor = await this._storage.find(this.Name(), parameters)
if (this._offset > 0) await cursor.skip(this._offset) if (this._offset > 0) await cursor.skip(this._offset)
if (this._limit > 0) await cursor.limit(this._limit) if (this._limit > 0) await cursor.limit(this._limit)
@@ -110,7 +115,7 @@ export abstract class Repo<T extends Entity<any>> {
return this return this
} }
async count(query?: Record<string, unknown>): Promise<number> { async count(query?: Record<string, any>): Promise<number> {
return this._storage.count(this.Name(), query) return this._storage.count(this.Name(), query)
} }
+5 -5
View File
@@ -20,19 +20,19 @@ export abstract class Storage {
this._dsn = dsn this._dsn = dsn
} }
abstract find(name: string, query: Record<string, unknown>): Promise<StorageCursor> abstract find(name: string, query: Record<string, any>): Promise<StorageCursor>
abstract save(name: string, uniqKey: string, data: Record<string, unknown>): Promise<string> abstract save(name: string, uniqKey: string, data: Record<string, any>): Promise<string>
abstract createSession(): StorageSession abstract createSession(): StorageSession
abstract count(name: string, query?: Record<string, unknown>): Promise<number> abstract count(name: string, query?: Record<string, any>): Promise<number>
abstract remove(collectionName: string, uniqKeyName: string, uniqKey: string): Promise<boolean> abstract remove(collectionName: string, uniqKeyName: string, uniqKey: string): Promise<boolean>
} }
/** @public */ /** @public */
export abstract class StorageSession { export abstract class StorageSession {
abstract start(options?: Record<string, unknown>): Promise<void> abstract start(options?: Record<string, any>): Promise<void>
abstract commit(fn: () => any, options?: Record<string, unknown>): Promise<void> abstract commit(fn: () => any, options?: Record<string, any>): Promise<void>
} }
+3 -3
View File
@@ -21,19 +21,19 @@ export class MongoStorage extends Storage {
await this._client.connect() await this._client.connect()
} }
async find(collectionName: string, query: Record<string, unknown>): Promise<StorageCursor> { async find(collectionName: string, query: Record<string, any>): Promise<StorageCursor> {
await this._connect() await this._connect()
const coll = await this._client.db().collection(collectionName) const coll = await this._client.db().collection(collectionName)
return coll.find(query) return coll.find(query)
} }
async count(collectionName: string, query: Record<string, unknown>): Promise<number> { async count(collectionName: string, query: Record<string, any>): Promise<number> {
await this._connect() await this._connect()
const coll = await this._client.db().collection(collectionName) const coll = await this._client.db().collection(collectionName)
return coll.countDocuments(query) return coll.countDocuments(query)
} }
async save(collectionName: string, uniqKey: string, data: Record<string, unknown>): Promise<string> { async save(collectionName: string, uniqKey: string, data: Record<string, any>): Promise<string> {
await this._connect() await this._connect()
const id = data[uniqKey] const id = data[uniqKey]
const coll = await this._client.db().collection(collectionName) const coll = await this._client.db().collection(collectionName)
+1
View File
@@ -6,3 +6,4 @@ export { Data, ValuesObject } from './app/data'
export { Entity, EntityConstructor, ErrEntityHasNoUniqKeyValue } from './app/entity' export { Entity, EntityConstructor, ErrEntityHasNoUniqKeyValue } from './app/entity'
export { Repo, ErrFoundNotUniqEntity, ErrEntityNotFound } from './app/repo' export { Repo, ErrFoundNotUniqEntity, ErrEntityNotFound } from './app/repo'
export { Storage, StorageCursor, ErrStorage, ErrNoSession, StorageSession } from './app/storage' export { Storage, StorageCursor, ErrStorage, ErrNoSession, StorageSession } from './app/storage'
export { EntityManager } from './app/entity/manager'