Last active
April 27, 2023 15:50
-
-
Save matheusmv/e3765a43bb1916b5b028c3099068daa2 to your computer and use it in GitHub Desktop.
dummy decorator method for cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class User { | |
createdAt: Date = new Date(); | |
constructor( | |
public id: number, | |
public username: string, | |
public password: string, | |
public email: string | |
) { } | |
} | |
interface Repository<K, T> { | |
findById(id: K): T | null; | |
findAll(): T[]; | |
save(getId: (o: T) => K, o: T): void; | |
saveAll(getId: (o: T) => K, ...o: T[]): void; | |
update(getId: (o: T) => K, o: T): void; | |
deleteById(id: K): void; | |
} | |
interface ICache<K, V> { | |
putObject(k: K, o: V): void; | |
getObject(k: K, dbQueryCmd: () => V): V | null; | |
deleteObject(k: K): void; | |
} | |
class MemDB<K, T> implements Repository<K, T> { | |
private db: Map<K, T> = new Map(); | |
findById(id: K): T | null { | |
const entity = this.db.get(id); | |
return entity || null; | |
} | |
findAll(): T[] { | |
const entities = [...this.db.values()]; | |
return entities; | |
} | |
save(getId: (o: T) => K, o: T): void { | |
this.db.set(getId(o), o); | |
} | |
saveAll(getId: (o: T) => K, ...o: T[]): void { | |
o.forEach((entity) => this.db.set(getId(entity), entity)); | |
} | |
update(getId: (o: T) => K, o: T): void { | |
this.db.set(getId(o), o); | |
} | |
deleteById(id: K): void { | |
this.db.delete(id); | |
} | |
} | |
class MemCache<K, V> implements ICache<K, V> { | |
private cache: Map<K, { value: V, et: number }> = new Map(); | |
constructor(private readonly expiryTimeInMinutes: number) { } | |
private addMinutes(minutes: number): number { | |
return Date.now() + minutes * 60000; | |
} | |
private buildValueWithExpiryTime(v: V): { value: V, et: number } { | |
return { | |
value: v, | |
et: this.addMinutes(this.expiryTimeInMinutes) | |
}; | |
} | |
putObject(k: K, o: V): void { | |
this.cache.set(k, this.buildValueWithExpiryTime(o)); | |
} | |
getObject(k: K, dbQueryCmd: () => V): V | null { | |
const obj = this.cache.get(k); | |
if (obj && obj.et > Date.now()) { | |
console.log("get from cache"); | |
return obj.value; | |
} | |
const entityFromDB = dbQueryCmd(); | |
if (entityFromDB) | |
this.putObject(k, entityFromDB); | |
return entityFromDB; | |
} | |
deleteObject(k: K): void { | |
this.cache.delete(k); | |
} | |
} | |
const globalCache = new MemCache<number, User>(5); | |
function cacheable(action: 'SAVE' | 'UPDATE' | 'DELETE') { | |
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { | |
const method = descriptor.value; | |
descriptor.value = function (...args: any[]) { | |
switch (action) { | |
case 'SAVE': { | |
const [id] = args; | |
return globalCache.getObject(id, () => method.apply(this, args)); | |
} | |
case 'UPDATE': { | |
const [obj] = args; | |
globalCache.putObject(obj['id'], obj); | |
return method.apply(this, args); | |
} | |
case 'DELETE': { | |
const [id] = args; | |
globalCache.deleteObject(id); | |
return method.apply(this, args); | |
} | |
} | |
} | |
} | |
} | |
class UserService { | |
constructor(private repository: Repository<number, User>) { } | |
findAllUsers(): User[] { | |
return this.repository.findAll(); | |
} | |
@cacheable("SAVE") | |
findUserById(id: number): User | null { | |
return this.repository.findById(id); | |
} | |
createUser(user: User): void { | |
this.repository.save((u: User) => u.id, user); | |
} | |
createUsers(...users: User[]): void { | |
this.repository.saveAll((u: User) => u.id, ...users); | |
} | |
@cacheable("UPDATE") | |
updateUser(user: User): void { | |
this.repository.update((u: User) => u.id, user); | |
} | |
@cacheable("DELETE") | |
deleteUserById(id: number): void { | |
this.repository.deleteById(id); | |
} | |
} | |
const userService = new UserService(new MemDB<number, User>()); | |
userService.createUsers( | |
new User(1, 'jhon', '12345', 'jhon@email.com'), | |
new User(2, 'alex', '12345', 'alex@email.com'), | |
new User(3, 'mary', '12345', 'mary@email.com'), | |
new User(4, 'carl', '12345', 'carl@email.com'), | |
); | |
console.log(userService.findUserById(3)); | |
let test = userService.findUserById(3) as User; | |
test.email = 'new-email@email.com'; | |
userService.updateUser(test); | |
console.log(userService.findUserById(3)); | |
console.log(userService.findUserById(3)); | |
console.log(userService.findUserById(3)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment