Skip to content

Commit

Permalink
feat: Saving message and VC meta data
Browse files Browse the repository at this point in the history
  • Loading branch information
simonas-notcat committed Dec 9, 2019
1 parent 8bf6a9d commit 1928125
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 74 deletions.
136 changes: 109 additions & 27 deletions packages/daf-data-store/src/data-store.ts
Expand Up @@ -201,15 +201,18 @@ export class DataStore {
async allIdentities() {
const vcSubjects = await this.db.rows('select distinct sub as did from verifiable_credentials', null)
const vcIssuers = await this.db.rows('select distinct iss as did from verifiable_credentials', null)
const messageSubjects = await this.db.rows(
'select distinct sub as did from messages where sub is not null',
const messageReceivers = await this.db.rows(
'select distinct receiver as did from messages where receiver is not null',
null,
)
const messageSenders = await this.db.rows(
'select distinct sender as did from messages where sender is not null',
null,
)
const messageIssuers = await this.db.rows('select distinct iss as did from messages', null)
const uniqueDids = [
...new Set([
...messageSubjects.map((item: any) => item.did),
...messageIssuers.map((item: any) => item.did),
...messageReceivers.map((item: any) => item.did),
...messageSenders.map((item: any) => item.did),
...vcIssuers.map((item: any) => item.did),
...vcSubjects.map((item: any) => item.did),
]),
Expand Down Expand Up @@ -244,8 +247,8 @@ export class DataStore {
}

async latestMessageTimestamps() {
let query =
'SELECT * from (select sub as did, nbf as timestamp, source_type as sourceType FROM messages ORDER BY nbf desc) GROUP BY did, sourceType'
let query = `SELECT * FROM ( SELECT m.id, m."timestamp", m.sender AS did, md. "type" AS sourceType, md.id AS sourceId FROM messages AS m
LEFT JOIN messages_meta_data AS md ON m.id = md.message_id) GROUP BY did, sourceType`

return await this.db.rows(query, [])
}
Expand All @@ -264,42 +267,121 @@ export class DataStore {
}

async saveMessage(message: Message) {
const query = sql
.insert('messages', {
hash: message.id,
iss: message.from,
sub: message.to,
nbf: message.timestamp,
type: message.type,
tag: message.threadId,
jwt: message.raw,
data: message.data && JSON.stringify(message.data),
meta: message.meta && JSON.stringify(message.meta),
source_type: message.meta.type,
source_id: message.meta.id,
})
const messageId = message.id

// Check if the message is already saved
const searchQuery = sql
.select('id')
.from('messages')
.where({ id: messageId })
.toParams()
const searchResult = await this.db.rows(searchQuery.text, searchQuery.values)
if (searchResult.length > 0) {
this.updateMetaData(message)
} else {
const query = sql
.insert('messages', {
id: messageId,
sender: message.from,
receiver: message.to,
timestamp: message.timestamp,
type: message.type,
thread_id: message.threadId,
raw: message.raw,
data: message.data && JSON.stringify(message.data),
})
.toParams()

await this.db.run(query.text, query.values)

await this.saveMetaData(message)
await this.saveVerifiableCredentials(message)
}

await this.db.run(query.text, query.values)
return { hash: message.id, iss: { did: message.from } }
}

private async updateMetaData(message: Message) {
const { id, allMeta } = message
for (const metaData of allMeta) {
const query = sql
.select('type, id, data')
.from('messages_meta_data')
.where({
message_id: id,
type: metaData.type,
id: metaData.id,
})
.toParams()
const rows = await this.db.rows(query.text, query.values)
if (rows.length === 0) {
const insertQuery = sql
.insert('messages_meta_data', {
message_id: id,
type: metaData.type,
id: metaData.id,
data: metaData.data && JSON.stringify(metaData.data),
})
.toParams()
await this.db.run(insertQuery.text, insertQuery.values)
}
}
}

private async saveMetaData(message: Message) {
const messageId = message.id

for (const metaData of message.allMeta) {
const query = sql
.insert('messages_meta_data', {
message_id: messageId,
type: metaData.type,
id: metaData.id,
data: metaData.data && JSON.stringify(metaData.data),
})
.toParams()
await this.db.run(query.text, query.values)
}
}

async saveVerifiableCredentials(message: Message) {
const messageId = message.id

if (message.type == 'w3c.vp' || message.type == 'w3c.vc') {
for (const vc of message.vc) {
await this.saveVerifiableCredential(vc, message.id)
await this.saveVerifiableCredential(vc, messageId)
}
}

return { hash: message.id, iss: { did: message.from } }
}

async saveVerifiableCredential(vc: any, messageHash: string) {
async saveVerifiableCredential(vc: any, messageId: string) {
const verifiableCredential = vc.payload as any

const vcHash = blake.blake2bHex(vc.jwt)

const metaData = sql
.insert('verifiable_credentials_meta_data', {
message_id: messageId,
hash: vcHash,
})
.toParams()

await this.db.run(metaData.text, metaData.values)

// Check if
const searchQuery = sql
.select('hash')
.from('verifiable_credentials')
.where({ hash: vcHash })
.toParams()
const searchResult = await this.db.rows(searchQuery.text, searchQuery.values)
if (searchResult.length > 0) {
return vcHash
}

const query = sql
.insert('verifiable_credentials', {
hash: vcHash,
parent_hash: messageHash,
iss: verifiableCredential.iss,
sub: verifiableCredential.sub,
nbf: verifiableCredential.nbf,
Expand Down
53 changes: 25 additions & 28 deletions packages/daf-data-store/src/migrations/001.initial.ts
Expand Up @@ -4,28 +4,31 @@ export const initial: Migration = {
run: async (db: DbDriver) => {
await db.run(
`CREATE TABLE IF NOT EXISTS messages (
hash TEXT,
parent_hash TEXT,
iss TEXT,
sub TEXT,
id TEXT PRIMARY KEY,
thread_id TEXT,
sender TEXT,
receiver TEXT,
type TEXT,
tag TEXT,
data TEXT,
iat NUMERIC,
nbf NUMERIC,
jwt TEXT,
meta TEXT,
source_type TEXT,
source_id TEXT,
internal NUMERIC NOT NULL default 1
);`,
raw TEXT,
timestamp NUMERIC
);`,
[],
)

await db.run(
`CREATE TABLE IF NOT EXISTS messages_meta_data (
message_id TEXT,
data TEXT,
type TEXT,
id TEXT
);`,
[],
)

await db.run(
`CREATE TABLE IF NOT EXISTS verifiable_credentials (
hash TEXT,
parent_hash TEXT,
iss TEXT,
aud TEXT,
sub TEXT,
Expand All @@ -37,6 +40,14 @@ export const initial: Migration = {
[],
)

await db.run(
`CREATE TABLE IF NOT EXISTS verifiable_credentials_meta_data (
message_id TEXT,
hash TEXT
);`,
[],
)

await db.run(
`CREATE TABLE IF NOT EXISTS verifiable_credentials_fields (
parent_hash INTEGER,
Expand All @@ -49,19 +60,5 @@ export const initial: Migration = {
);`,
[],
)

await db.run(
`CREATE TRIGGER IF NOT EXISTS delete_messages BEFORE DELETE ON "messages" BEGIN
DELETE FROM verifiable_credentials where parent_hash = old.hash;
END;`,
[],
)

await db.run(
`CREATE TRIGGER IF NOT EXISTS delete_verifiable_credentials BEFORE DELETE ON "verifiable_credentials" BEGIN
DELETE FROM verifiable_credentials_fields where parent_hash = old.hash;
END;`,
[],
)
},
}
30 changes: 11 additions & 19 deletions packages/daf-data-store/src/migrations/002.second.ts
Expand Up @@ -2,37 +2,29 @@ import { DbDriver, Migration } from '../types'

export const second: Migration = {
run: async (db: DbDriver) => {
await db.run(`CREATE INDEX IF NOT EXISTS "messages_id" ON "messages" ("id");`, [])
await db.run(`CREATE INDEX IF NOT EXISTS "messages_thread_id" ON "messages" ("thread_id");`, [])
await db.run(`CREATE INDEX IF NOT EXISTS "messages_receiver" ON "messages" ("receiver");`, [])
await db.run(`CREATE INDEX IF NOT EXISTS "messages_sender" ON "messages" ("sender");`, [])
await db.run(
`CREATE INDEX IF NOT EXISTS "messages_hash" ON "messages" ("hash");`,
[],
)
await db.run(
`CREATE INDEX IF NOT EXISTS "messages_parent_hash" ON "messages" ("parent_hash");`,
[],
)
await db.run(
`CREATE INDEX IF NOT EXISTS "messages_sub" ON "messages" ("sub");`,
[],
)
await db.run(
`CREATE INDEX IF NOT EXISTS "messages_iss" ON "messages" ("iss");`,
`CREATE INDEX IF NOT EXISTS "messages_meta_data_message_id" ON "messages_meta_data" ("message_id");`,
[],
)

await db.run(
`CREATE INDEX IF NOT EXISTS "messages_source_type" ON "messages" ("source_type");`,
[],
)
await db.run(`CREATE INDEX IF NOT EXISTS "messages_meta_data_type" ON "messages_meta_data" ("type");`, [])

await db.run(`CREATE INDEX IF NOT EXISTS "messages_meta_data_id" ON "messages_meta_data" ("id");`, [])

await db.run(
`CREATE INDEX IF NOT EXISTS "messages_source_id" ON "messages" ("source_id");`,
`CREATE INDEX IF NOT EXISTS "verifiable_credentials_meta_data_message_id" ON "verifiable_credentials_meta_data" ("message_id");`,
[],
)

await db.run(
`CREATE INDEX IF NOT EXISTS "verifiable_credentials_parent_hash" ON "verifiable_credentials" ("parent_hash");`,
`CREATE INDEX IF NOT EXISTS "verifiable_credentials_meta_data_hash" ON "verifiable_credentials_meta_data" ("hash");`,
[],
)

await db.run(
`CREATE INDEX IF NOT EXISTS "verifiable_credentials_iss" ON "verifiable_credentials" ("iss");`,
[],
Expand Down

0 comments on commit 1928125

Please sign in to comment.