Skip to content

Commit

Permalink
Switch to structed identifier
Browse files Browse the repository at this point in the history
Signed-off-by: Jack Works <zjwpeter@gmail.com>
  • Loading branch information
Jack-Works committed May 22, 2019
1 parent b92f7d5 commit 5f22449
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 35 deletions.
20 changes: 10 additions & 10 deletions src/database/avatar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@ import { Identifier, PersonIdentifier } from './type'
//#region Schema
export type AvatarRecord = ArrayBuffer
export interface AvatarMetadataRecord {
identifier: Identifier
identifier: string
lastUpdateTime: Date
lastAccessTime: Date
}
interface AvatarDB extends DBSchema {
/** Use out-of-line keys */
avatars: {
value: AvatarRecord
key: [string, string, string, string] | [string, string, string]
key: string
}
/** Key is value.identifier */
metadata: {
value: AvatarMetadataRecord
key: [string, string, string, string] | [string, string, string]
key: string
}
}
//#endregion

const db = openDB<AvatarDB>('maskbook-avatar-store-v2', 1, {
const db = openDB<AvatarDB>('maskbook-avatar-cache-v2', 1, {
upgrade(db, oldVersion, newVersion, transaction) {
// Out line keys
const avatarStore = db.createObjectStore('avatars')
Expand All @@ -34,12 +34,12 @@ const db = openDB<AvatarDB>('maskbook-avatar-store-v2', 1, {
*/
export async function storeAvatarDB(id: Identifier, avatar: ArrayBuffer) {
const meta: AvatarMetadataRecord = {
identifier: id,
identifier: id.toString(),
lastUpdateTime: new Date(),
lastAccessTime: new Date(),
}
const t = (await db).transaction(['avatars', 'metadata'], 'readwrite')
const a = t.objectStore('avatars').put(avatar, id)
const a = t.objectStore('avatars').put(avatar, id.toString())
await t.objectStore('metadata').put(meta)
await a
return
Expand All @@ -49,7 +49,7 @@ export async function storeAvatarDB(id: Identifier, avatar: ArrayBuffer) {
*/
export async function queryAvatarDB(id: PersonIdentifier) {
const t = (await db).transaction('avatars')
const result = t.objectStore('avatars').get(id)
const result = t.objectStore('avatars').get(id.toString())

try {
updateAvatarMetaDB(id, { lastAccessTime: new Date() })
Expand All @@ -61,7 +61,7 @@ export async function queryAvatarDB(id: PersonIdentifier) {
*/
async function updateAvatarMetaDB(id: PersonIdentifier, newMeta: Partial<AvatarMetadataRecord>) {
const t = (await db).transaction('metadata', 'readwrite')
const meta = await t.objectStore('metadata').get(id)
const meta = await t.objectStore('metadata').get(id.toString())
const newRecord = Object.assign({}, meta, newMeta)
await t.objectStore('metadata').put(newRecord)
return newRecord
Expand Down Expand Up @@ -89,8 +89,8 @@ export async function deleteAvatarsDB(ids: PersonIdentifier[]) {
const t = (await db).transaction(['avatars', 'metadata'], 'readwrite')
const promises: Promise<void>[] = []
for (const id of ids) {
const a = t.objectStore('avatars').delete(id)
const b = t.objectStore('metadata').delete(id)
const a = t.objectStore('avatars').delete(id.toString())
const b = t.objectStore('metadata').delete(id.toString())
promises.push(a, b)
}
return
Expand Down
4 changes: 4 additions & 0 deletions src/database/group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Not implementing this now.
*/
export default undefined
7 changes: 3 additions & 4 deletions src/database/people.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,20 @@ enum Relation {
* I banned this person.
* (Only available on some social networks)
*/
IBanned = 'i banned',
IBanned = 'I banned',
/**
* This person bans me.
* (Only available on some social networks)
*/
IAmBanned = 'i am banned',
IAmBanned = 'I am banned',
/** I am following this person. So their post can appear in my timeline. */
following = 'following',
/** This person follows me. So my post can appear in their timeline. */
followed = 'followed',
}
export interface PersonRecord {
identifier: PersonIdentifier
name: string
// nickname: string
nickname: string
relation: Relation[]
/** Last check time of relation */
relationLastCheckTime: Date
Expand Down
21 changes: 0 additions & 21 deletions src/database/type.d.ts

This file was deleted.

74 changes: 74 additions & 0 deletions src/database/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
type Identifiers = 'person' | 'group' | 'post'
const fromString = Symbol()
function noSlash(str: string) {
if (str.split('/')[1]) throw new TypeError('Cannot contain / in a part of identifier')
}
export abstract class Identifier {
abstract toString(): string
static fromString(id: string): Identifier | null {
const [type, ...rest] = id.split(':') as [Identifiers, string]
switch (type) {
case 'person':
return PersonIdentifier[fromString](rest.join(''))
case 'group':
return GroupIdentifier[fromString](rest.join(''))
case 'post':
return PostIdentifier[fromString](rest.join(''))
default:
return null
}
}
}
export class PersonIdentifier extends Identifier {
/**
* @param network - Network belongs to
* @param userId - User ID
*/
constructor(public network: string, public userId: string) {
super()
noSlash(network)
noSlash(userId)
}
toString() {
return `person:${this.network}/${this.userId}`
}
static [fromString](str: string) {
const [network, userId] = str.split('/')
if (!network || !userId) return null
return new PersonIdentifier(network, userId)
}
}
export class GroupIdentifier extends Identifier {
constructor(public network: string, public groupId: string, public virtual = false) {
super()
noSlash(network)
noSlash(groupId)
}
toString() {
return `group:${this.network}/${this.groupId}/${this.virtual ? 'virtual' : 'real'}`
}
static [fromString](str: string) {
const [network, groupId, virtual] = str.split('/')
if (!network || !groupId || !virtual) return null
return new GroupIdentifier(network, groupId, virtual === 'virtual')
}
}
export class PostIdentifier extends Identifier {
/**
* If identifier is a PostIdentifier, that means this post is binded with other post in some kind
* e.g. a comment.
*/
constructor(public identifier: Identifier, public postId: string) {
super()
noSlash(postId)
}
toString() {
return `post:${this.postId}/${this.identifier.toString()}`
}
static [fromString](str: string) {
const [postId, ...identifier] = str.split('/')
const id = Identifier.fromString(identifier.join('/'))
if (!id || !postId) return null
return new PostIdentifier(id, postId)
}
}

0 comments on commit 5f22449

Please sign in to comment.